[SCM] Azureus/Vuze packaging for Debian branch, master, updated. debian/4.2.0.8-2-20-gca0dd11

Adrian Perez adrianperez-guest at alioth.debian.org
Wed Dec 2 15:22:45 UTC 2009


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Azureus/Vuze packaging for Debian".

The branch, master has been updated
       via  ca0dd1123721f57a182fbf9ccd79df916108e7c3 (commit)
       via  298ddc3cbaa913b79a2826c97d8ffd2f6e4002cc (commit)
       via  a9c97bb85eaf7d3e701b91eb0a7922f1efb08f9b (commit)
       via  2b87d9d28ce17945dc51ade8c7491b987c5759ac (commit)
       via  50ab4650c2b5cea059104e8565a7efabf6e475fa (commit)
       via  72064e0ba68a9aaf0a980dbd7540680b892fc970 (commit)
       via  ddf3f27efba187a8bf9b73da8e882f690e330784 (commit)
       via  47cfd0bfee71361452f1b962544fd98c1865ee6e (commit)
       via  f4b150d955080fa4305e3362b38b4520bd166533 (commit)
       via  8c274a91318b032dbdbbb0d1acc3a7a13c82635c (commit)
       via  db9588badcbf6e5e1cfb54bf0e1e082acc13082b (commit)
       via  91a1907c48b54f21285a07ebb6f0900ebf5a1001 (commit)
       via  b70cee75a9d15b86f298f16a66979545d06d51be (commit)
       via  7f589b99ccb4db616a78d45152378a580a4abf08 (commit)
      from  c2fc248b45e9e56e75019b9fcd56134addb21c8f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ca0dd1123721f57a182fbf9ccd79df916108e7c3
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Wed Dec 2 09:26:19 2009 -0500

    debian/docs: Remove README.source reference

commit 298ddc3cbaa913b79a2826c97d8ffd2f6e4002cc
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Wed Dec 2 09:14:59 2009 -0500

    Prepare snapshot #2.

commit a9c97bb85eaf7d3e701b91eb0a7922f1efb08f9b
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Wed Dec 2 09:11:59 2009 -0500

    Add Closes for Launchpad bug claiming new release.

commit 2b87d9d28ce17945dc51ade8c7491b987c5759ac
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Wed Dec 2 08:59:46 2009 -0500

    Use "3.0 (quilt)" source package format.

commit 50ab4650c2b5cea059104e8565a7efabf6e475fa
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Wed Dec 2 08:52:39 2009 -0500

    debian/control: Allow uploads for Debian Maintainers.

commit 72064e0ba68a9aaf0a980dbd7540680b892fc970
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Wed Dec 2 08:50:24 2009 -0500

    debian/patches/fixes/platform.diff: Fix patch.

commit ddf3f27efba187a8bf9b73da8e882f690e330784
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Wed Dec 2 08:27:59 2009 -0500

    Remove build/libs/JavaApplicationStub

commit 47cfd0bfee71361452f1b962544fd98c1865ee6e
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Mon Nov 30 23:28:23 2009 -0500

    debian/azureus.desktop: Improve Comment for Desktop Entry.

commit f4b150d955080fa4305e3362b38b4520bd166533
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Mon Nov 30 22:50:07 2009 -0500

    debian/changelog: Update changelog for snapshot

commit 8c274a91318b032dbdbbb0d1acc3a7a13c82635c
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Mon Nov 30 19:34:34 2009 -0500

    Refresh patches (start considering patch removal)

commit db9588badcbf6e5e1cfb54bf0e1e082acc13082b
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Mon Nov 30 19:15:52 2009 -0500

    debian/patches: Remove utf8-encoding (released upstream)

commit 91a1907c48b54f21285a07ebb6f0900ebf5a1001
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Mon Nov 30 19:03:50 2009 -0500

    debian/patches: Remove fixes/multi-announce-deadlock.diff

commit b70cee75a9d15b86f298f16a66979545d06d51be
Merge: c2fc248b45e9e56e75019b9fcd56134addb21c8f 7f589b99ccb4db616a78d45152378a580a4abf08
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Mon Nov 30 18:59:12 2009 -0500

    Merge commit 'upstream/4.3.0.0'

commit 7f589b99ccb4db616a78d45152378a580a4abf08
Author: Adrian Perez <adrianperez.deb at gmail.com>
Date:   Mon Nov 30 18:59:10 2009 -0500

    Imported Upstream version 4.3.0.0

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog.txt                                      |   76 +
 .../activities/VuzeActivitiesBuddyInvited.java     |   66 -
 .../activities/VuzeActivitiesConstants.java        |   73 -
 .../azureus/activities/VuzeActivitiesEntry.java    |    5 -
 .../activities/VuzeActivitiesEntryBuddy.java       |  114 --
 .../activities/VuzeActivitiesEntryBuddyLinkup.java |   56 -
 .../VuzeActivitiesEntryBuddyRequest.java           |   90 -
 .../VuzeActivitiesEntryContentShare.java           |  207 --
 .../azureus/activities/VuzeActivitiesManager.java  |  258 +--
 com/aelitis/azureus/buddy/QueuedVuzeShare.java     |  169 --
 com/aelitis/azureus/buddy/VuzeBuddy.java           |  206 --
 com/aelitis/azureus/buddy/VuzeBuddyCreator.java    |   52 -
 com/aelitis/azureus/buddy/VuzeBuddyListener.java   |   62 -
 com/aelitis/azureus/buddy/VuzeShareable.java       |   79 -
 com/aelitis/azureus/buddy/chat/Chat.java           |  210 --
 com/aelitis/azureus/buddy/chat/ChatDiscussion.java |  142 --
 com/aelitis/azureus/buddy/chat/ChatListener.java   |   11 -
 com/aelitis/azureus/buddy/chat/ChatMessage.java    |  176 --
 .../azureus/buddy/chat/ChatMessageListener.java    |   30 -
 .../azureus/buddy/chat/DiscussionListener.java     |    8 -
 .../azureus/buddy/impl/VuzeBuddyFakeImpl.java      |   80 -
 com/aelitis/azureus/buddy/impl/VuzeBuddyImpl.java  |  758 -------
 .../azureus/buddy/impl/VuzeBuddyManager.java       | 1813 -----------------
 .../buddy/impl/VuzeBuddyMessageListener.java       |   39 -
 .../azureus/buddy/impl/VuzeQueuedShares.java       |  223 ---
 .../azureus/core/cnetwork/ContentNetwork.java      |    2 +
 .../core/cnetwork/impl/ContentNetworkVuze.java     |    2 +-
 .../cnetwork/impl/ContentNetworkVuzeGeneric.java   |   11 +-
 .../azureus/core/content/RelatedContent.java       |   98 +-
 .../core/content/RelatedContentManager.java        | 1214 +++++++++++-
 .../azureus/core/crypto/VuzeCryptoManager.java     |   46 +-
 com/aelitis/azureus/core/devices/Device.java       |    9 +
 .../azureus/core/devices/DeviceListener.java       |   30 +
 .../azureus/core/devices/DeviceManager.java        |   25 +-
 .../core/devices/DeviceOfflineDownload.java        |   40 +
 .../core/devices/DeviceOfflineDownloader.java      |   62 +
 .../devices/DeviceOfflineDownloaderListener.java   |   39 +
 .../devices/DeviceOfflineDownloaderManager.java    |   61 +
 .../azureus/core/devices/TranscodeTarget.java      |    4 +
 .../azureus/core/devices/impl/DeviceImpl.java      |  144 ++
 .../core/devices/impl/DeviceManagerImpl.java       |  260 ++-
 .../core/devices/impl/DeviceManagerRSSFeed.java    |  108 +-
 .../core/devices/impl/DeviceManagerUPnPImpl.java   |   91 +-
 .../devices/impl/DeviceMediaRendererManual.java    |   41 +
 .../devices/impl/DeviceOfflineDownloaderImpl.java  | 1678 ++++++++++++++++
 .../core/devices/impl/DeviceTivoManager.java       |  126 +-
 .../azureus/core/devices/impl/DeviceUPnPImpl.java  |   11 +
 .../core/devices/impl/TranscodeFileImpl.java       |   14 +
 .../core/devices/impl/TranscodeJobImpl.java        |    5 +-
 .../core/devices/impl/TranscodeQueueImpl.java      |   21 +-
 com/aelitis/azureus/core/dht/DHT.java              |   31 +-
 .../azureus/core/dht/DHTOperationAdapter.java      |    5 +-
 .../azureus/core/dht/DHTOperationListener.java     |    3 +-
 .../azureus/core/dht/DHTStorageAdapter.java        |    1 +
 .../azureus/core/dht/control/DHTControl.java       |   55 +-
 .../core/dht/control/DHTControlAdapter.java        |    1 +
 .../core/dht/control/impl/DHTControlImpl.java      |  710 ++++++-
 com/aelitis/azureus/core/dht/db/DHTDB.java         |   17 +-
 com/aelitis/azureus/core/dht/db/DHTDBFactory.java  |    2 +
 .../azureus/core/dht/db/impl/DHTDBImpl.java        | 2103 +++++++++++++++++---
 .../azureus/core/dht/db/impl/DHTDBMapping.java     |  166 ++-
 .../azureus/core/dht/db/impl/DHTDBValueImpl.java   |   29 +-
 com/aelitis/azureus/core/dht/impl/DHTImpl.java     |   23 +-
 com/aelitis/azureus/core/dht/impl/DHTLog.java      |    2 +-
 com/aelitis/azureus/core/dht/impl/Test.java        |   53 +-
 .../core/dht/nat/impl/DHTNATPuncherImpl.java       |    9 +-
 com/aelitis/azureus/core/dht/router/DHTRouter.java |    4 +-
 .../core/dht/router/impl/DHTRouterImpl.java        |   30 +-
 .../azureus/core/dht/transport/DHTTransport.java   |    3 +
 .../core/dht/transport/DHTTransportContact.java    |   12 +
 .../dht/transport/DHTTransportQueryStoreReply.java |   34 +
 .../dht/transport/DHTTransportReplyHandler.java    |    7 +
 .../transport/DHTTransportReplyHandlerAdapter.java |   10 +
 .../dht/transport/DHTTransportRequestHandler.java  |    8 +
 .../core/dht/transport/DHTTransportStats.java      |    4 +
 .../core/dht/transport/DHTTransportValue.java      |    9 +
 .../loopback/DHTTransportLoopbackContactImpl.java  |   19 +
 .../loopback/DHTTransportLoopbackImpl.java         |   18 +
 .../core/dht/transport/udp/DHTTransportUDP.java    |   17 +-
 .../udp/impl/DHTTransportUDPContactImpl.java       |   19 +
 .../transport/udp/impl/DHTTransportUDPImpl.java    |  278 +++-
 .../dht/transport/udp/impl/DHTUDPPacketData.java   |   29 +-
 .../dht/transport/udp/impl/DHTUDPPacketHelper.java |   12 +
 .../udp/impl/DHTUDPPacketReplyQueryStorage.java    |  193 ++
 .../udp/impl/DHTUDPPacketRequestQueryStorage.java  |  168 ++
 .../udp/impl/DHTUDPPacketRequestStore.java         |    4 +-
 .../core/dht/transport/udp/impl/DHTUDPUtils.java   |   95 +-
 .../azureus/core/dht/transport/udp/impl/Test.java  |   32 +
 .../transport/util/DHTTransportRequestCounter.java |   15 +
 .../dht/transport/util/DHTTransportStatsImpl.java  |   60 +-
 .../azureus/core/diskmanager/cache/CacheFile.java  |   12 +-
 .../cache/impl/CacheFileManagerImpl.java           |   41 +-
 .../diskmanager/cache/impl/CacheFileWithCache.java |   20 +-
 .../cache/impl/CacheFileWithoutCache.java          |   20 +-
 .../cache/impl/CacheFileWithoutCacheMT.java        |   18 +-
 .../azureus/core/diskmanager/cache/impl/Test.java  |  680 +++++++-
 .../azureus/core/diskmanager/file/FMFile.java      |   12 +-
 .../core/diskmanager/file/impl/FMFileAccess.java   |   15 +-
 .../diskmanager/file/impl/FMFileAccessCompact.java |   37 +-
 .../file/impl/FMFileAccessController.java          |   76 +-
 .../diskmanager/file/impl/FMFileAccessLinear.java  |   21 +-
 .../file/impl/FMFileAccessPieceReorderer.java      |  832 ++++++++
 .../core/diskmanager/file/impl/FMFileImpl.java     |   24 +-
 .../core/diskmanager/file/impl/FMFileLimited.java  |   20 +
 .../diskmanager/file/impl/FMFileUnlimited.java     |   22 +-
 .../core/download/DownloadManagerEnhancer.java     |   35 -
 .../core/download/EnhancedDownloadManager.java     |  125 +--
 .../drm/msdrm/CheckVersionRequiredException.java   |    9 -
 .../core/drm/msdrm/DRMUpdateRequiredException.java |    9 -
 .../msdrm/ExceededDRMDeliveryLimitException.java   |    9 -
 .../azureus/core/drm/msdrm/LicenseAquirer.java     |  335 ----
 .../core/drm/msdrm/LicenseAquisitionException.java |    9 -
 com/aelitis/azureus/core/impl/AzureusCoreImpl.java |   23 +-
 com/aelitis/azureus/core/lws/LWSDiskManager.java   |   15 +-
 .../azureus/core/lws/LWSDiskManagerState.java      |    7 +
 com/aelitis/azureus/core/lws/LWSDownload.java      |    6 +
 com/aelitis/azureus/core/lws/LWSTorrent.java       |    7 +
 .../core/messenger/ClientMessageContext.java       |   13 -
 .../core/messenger/ClientMessageContextImpl.java   |   25 -
 .../azureus/core/messenger/PlatformMessage.java    |   42 -
 .../azureus/core/messenger/PlatformMessenger.java  |  449 ++---
 .../core/messenger/browser/BrowserMessage.java     |   20 -
 .../core/messenger/browser/BrowserTransaction.java |  246 ---
 .../browser/BrowserTransactionManager.java         |  181 --
 .../listeners/AbstractTransactionalListener.java   |  221 --
 .../messenger/config/PlatformBuddyMessenger.java   |  378 ----
 .../messenger/config/PlatformConfigMessenger.java  |   33 +-
 .../config/PlatformContentNetworkMessenger.java    |    9 +
 .../core/messenger/config/PlatformDCAdManager.java |  535 -----
 .../messenger/config/PlatformDevicesMessenger.java |    6 +
 .../config/PlatformKeyExchangeMessenger.java       |  138 --
 .../messenger/config/PlatformRatingMessenger.java  |  438 ----
 .../messenger/config/PlatformRelayMessenger.java   |  444 -----
 .../config/PlatformSubscriptionsMessenger.java     |   27 +-
 .../messenger/config/PlatformTorrentMessenger.java |   77 +-
 .../config/PlatformVuzeActivitiesMessenger.java    |    1 -
 .../messenger/config/RatingUpdateListener2.java    |   26 -
 .../messenger/config/VuzeBuddySyncListener.java    |   29 -
 .../core/messenger/config/VuzeRelayListener.java   |   36 -
 com/aelitis/azureus/core/metasearch/Engine.java    |    1 +
 com/aelitis/azureus/core/metasearch/Result.java    |   41 +-
 .../core/metasearch/impl/DateParserRegex.java      |    9 +-
 .../azureus/core/metasearch/impl/EngineImpl.java   |  164 ++-
 .../core/metasearch/impl/ExternalLoginWindow.java  |   32 +-
 .../core/metasearch/impl/MetaSearchImpl.java       |   81 +-
 .../metasearch/impl/MetaSearchManagerImpl.java     |    4 +-
 .../core/metasearch/impl/plugin/PluginEngine.java  |   31 +-
 .../core/metasearch/impl/plugin/PluginResult.java  |    7 +
 .../core/metasearch/impl/web/WebResult.java        |   36 +
 .../core/metasearch/impl/web/rss/RSSEngine.java    |   51 +
 .../metasearch/utils/MomentsAgoDateFormatter.java  |   22 +-
 .../core/monitoring/thread/AEThreadMonitor.java    |   18 +-
 .../core/networkmanager/admin/NetworkAdmin.java    |    9 +
 .../admin/impl/NetworkAdminImpl.java               |  126 ++-
 .../core/networkmanager/impl/ByteBucketST.java     |    8 +-
 .../impl/tcp/VirtualChannelSelectorImpl.java       |    8 +-
 .../impl/udp/UDPConnectionManager.java             |   65 +-
 .../azureus/core/pairing/PairedService.java        |   35 +
 .../core/pairing/PairingConnectionData.java        |   44 +
 .../azureus/core/pairing/PairingException.java     |   42 +
 .../azureus/core/pairing/PairingManager.java       |   55 +
 .../core/pairing/PairingManagerFactory.java        |   34 +
 .../core/pairing/PairingManagerListener.java       |   30 +
 .../core/pairing/impl/PairingManagerImpl.java      | 1134 +++++++++++
 .../peermanager/messaging/azureus/AZHandshake.java |   27 +-
 .../messaging/azureus/AZMessageFactory.java        |   12 +-
 .../messaging/bittorrent/ltep/LTHandshake.java     |   25 +-
 .../piecepicker/impl/PiecePickerImpl.java          |    7 +-
 .../peermanager/unchoker/UnchokerUtilTest.java     |    7 +-
 .../utils/BTPeerIDByteDecoderDefinitions.java      |   10 +-
 .../utils/BTPeerIDByteDecoderUtils.java            |    1 +
 .../azureus/core/rssgen/RSSGeneratorPlugin.java    |  257 +++
 .../core/security/impl/CryptoHandlerECC.java       |   70 +-
 .../core/security/impl/CryptoManagerImpl.java      |   42 +-
 com/aelitis/azureus/core/subs/Subscription.java    |   12 +
 .../azureus/core/subs/SubscriptionManager.java     |   14 +-
 .../azureus/core/subs/SubscriptionResult.java      |   11 +
 .../core/subs/impl/SubscriptionHistoryImpl.java    |    8 +
 .../azureus/core/subs/impl/SubscriptionImpl.java   |   25 +-
 .../core/subs/impl/SubscriptionManagerImpl.java    |   61 +-
 .../core/subs/impl/SubscriptionRSSFeed.java        |  328 +++
 .../core/subs/impl/SubscriptionResultImpl.java     |   59 +-
 .../azureus/core/torrent/GlobalRatingUtils.java    |  168 --
 .../core/torrent/MetaDataUpdateListener.java       |   33 -
 .../core/torrent/PlatformRatingInfoList.java       |  171 --
 .../azureus/core/torrent/PlatformTorrentUtils.java |  356 +---
 .../azureus/core/torrent/RatingInfoList.java       |   30 -
 .../azureus/core/torrent/SingleUserRatingInfo.java |   77 -
 com/aelitis/azureus/core/util/CopyOnWriteList.java |   15 +-
 com/aelitis/azureus/core/util/CopyOnWriteMap.java  |    2 +-
 .../azureus/core/util/FeatureAvailability.java     |    9 +
 com/aelitis/azureus/core/util/HTTPUtils.java       |    2 +
 .../azureus/core/util/MultiPartDecoder.java        |  392 ++++
 .../azureus/core/util/bloom/BloomFilter.java       |    5 +
 .../core/util/bloom/BloomFilterFactory.java        |    9 +
 .../core/util/bloom/impl/BloomFilterAddOnly.java   |   20 +
 .../util/bloom/impl/BloomFilterAddRemove4Bit.java  |   20 +
 .../util/bloom/impl/BloomFilterAddRemove8Bit.java  |   20 +
 .../core/util/bloom/impl/BloomFilterImpl.java      |   70 +
 .../core/util/bloom/impl/BloomFilterRotator.java   |   57 +
 .../core/versioncheck/VersionCheckClient.java      |   69 +-
 com/aelitis/azureus/jdk15/Java15Initialiser.java   |    2 +-
 .../azureus/login/NotLoggedInException.java        |   68 -
 com/aelitis/azureus/plugins/dht/DHTPlugin.java     |   49 +-
 .../azureus/plugins/dht/DHTPluginContact.java      |    5 +
 .../plugins/dht/impl/DHTPluginContactImpl.java     |   28 +
 .../azureus/plugins/dht/impl/DHTPluginImpl.java    |   28 +-
 .../plugins/dht/impl/DHTPluginStorageManager.java  |   12 +-
 .../plugins/extseed/ExternalSeedPlugin.java        |   32 +-
 .../plugins/extseed/ExternalSeedReader.java        |    6 +-
 .../extseed/impl/ExternalSeedReaderImpl.java       |  113 +-
 .../extseed/impl/ExternalSeedReaderRequest.java    |   30 +-
 .../ExternalSeedReaderFactoryGetRight.java         |    7 +
 .../impl/getright/ExternalSeedReaderGetRight.java  |   94 +-
 .../impl/webseed/ExternalSeedReaderWebSeed.java    |    3 +-
 .../extseed/util/ExternalSeedHTTPDownloader.java   |  582 +------
 .../util/ExternalSeedHTTPDownloaderLinear.java     |  651 ++++++
 .../util/ExternalSeedHTTPDownloaderListener.java   |    3 +
 .../util/ExternalSeedHTTPDownloaderRange.java      |  759 +++++++
 .../azureus/plugins/magnet/MagnetPlugin.java       |   16 +-
 .../azureus/plugins/net/buddy/BuddyPlugin.java     |  213 ++-
 .../plugins/net/buddy/BuddyPluginBuddy.java        |   25 +
 .../plugins/net/buddy/swt/BuddyPluginView.java     |    8 +-
 .../plugins/net/buddy/swt/BuddyPluginViewChat.java |    3 +-
 .../net/buddy/swt/BuddyPluginViewInstance.java     |  124 +-
 .../removerules/DownloadRemoveRulesPlugin.java     |   33 +-
 .../plugins/sharing/hoster/ShareHosterPlugin.java  |  345 ++--
 .../defaultplugin/StartStopRulesDefaultPlugin.java |   29 +-
 .../defaultplugin/ui/swt/ConfigSectionQueue.java   |    4 -
 .../defaultplugin/ui/swt/ConfigSectionSeeding.java |    4 -
 .../ui/swt/ConfigSectionSeedingAutoStarting.java   |    2 -
 .../ui/swt/ConfigSectionSeedingFirstPriority.java  |    1 -
 .../ui/swt/ConfigSectionSeedingIgnore.java         |   15 +-
 .../plugins/tracker/dht/DHTTrackerPlugin.java      |  351 +++--
 com/aelitis/azureus/ui/UIFunctions.java            |    5 +-
 .../azureus/ui/UIFunctionsUserPrompter.java        |   11 +-
 .../azureus/ui/UserPrompterResultListener.java     |    6 +
 .../azureus/ui/common/table/TableColumnCore.java   |    2 +
 com/aelitis/azureus/ui/common/table/TableView.java |   14 -
 .../ui/common/table/impl/TableColumnImpl.java      |   14 +-
 .../ui/common/table/impl/TableViewImpl.java        |    6 +-
 com/aelitis/azureus/ui/images/btn_details.png      |  Bin 563 -> 0 bytes
 com/aelitis/azureus/ui/images/buddy_add.png        |  Bin 545 -> 0 bytes
 .../azureus/ui/images/buddy_add_to_share.png       |  Bin 258 -> 0 bytes
 .../ui/images/buddy_add_to_share_selected.png      |  Bin 414 -> 0 bytes
 .../azureus/ui/images/buddy_default_avatar.png     |  Bin 1304 -> 0 bytes
 .../azureus/ui/images/buddy_prompt_image.png       |  Bin 937 -> 0 bytes
 .../azureus/ui/images/buddy_remove-over.png        |  Bin 195 -> 0 bytes
 com/aelitis/azureus/ui/images/buddy_remove.png     |  Bin 197 -> 0 bytes
 .../ui/images/button_dialog_center-over.png        |  Bin 117 -> 0 bytes
 .../azureus/ui/images/button_dialog_center.png     |  Bin 106 -> 0 bytes
 .../azureus/ui/images/button_dialog_close-over.png |  Bin 231 -> 0 bytes
 .../azureus/ui/images/button_dialog_close.png      |  Bin 96 -> 0 bytes
 .../azureus/ui/images/button_dialog_left-over.png  |  Bin 179 -> 0 bytes
 .../azureus/ui/images/button_dialog_left.png       |  Bin 176 -> 0 bytes
 .../azureus/ui/images/button_dialog_min-over.png   |  Bin 216 -> 0 bytes
 .../azureus/ui/images/button_dialog_min.png        |  Bin 91 -> 0 bytes
 .../azureus/ui/images/button_dialog_right-over.png |  Bin 163 -> 0 bytes
 .../azureus/ui/images/button_dialog_right.png      |  Bin 162 -> 0 bytes
 .../azureus/ui/images/button_skin_close-over.png   |  Bin 231 -> 0 bytes
 .../azureus/ui/images/button_skin_close.png        |  Bin 96 -> 0 bytes
 com/aelitis/azureus/ui/images/chatNotification.png |  Bin 530 -> 0 bytes
 com/aelitis/azureus/ui/images/clock_wait.png       |  Bin 528 -> 0 bytes
 com/aelitis/azureus/ui/images/device_bel_logo.png  |  Bin 0 -> 2062 bytes
 .../azureus/ui/images/friend_online_icon.png       |  Bin 333 -> 0 bytes
 com/aelitis/azureus/ui/images/grey_bubble.png      |  Bin 1102 -> 0 bytes
 com/aelitis/azureus/ui/images/ic_thumbs.png        |  Bin 920 -> 0 bytes
 com/aelitis/azureus/ui/images/ic_thumbsDown.png    |  Bin 927 -> 0 bytes
 com/aelitis/azureus/ui/images/ic_thumbsUp.png      |  Bin 983 -> 0 bytes
 com/aelitis/azureus/ui/images/large_red_bubble.png |  Bin 1315 -> 0 bytes
 com/aelitis/azureus/ui/images/no_friends.png       |  Bin 2053 -> 0 bytes
 com/aelitis/azureus/ui/images/rateme.png           |  Bin 1755 -> 0 bytes
 .../azureus/ui/images/rateme_button-disabled.png   |  Bin 1108 -> 0 bytes
 com/aelitis/azureus/ui/images/rateme_button.png    |  Bin 1181 -> 0 bytes
 com/aelitis/azureus/ui/images/rateme_down.png      |  Bin 1578 -> 0 bytes
 com/aelitis/azureus/ui/images/rateme_up.png        |  Bin 1548 -> 0 bytes
 com/aelitis/azureus/ui/images/red_bubble.png       |  Bin 1185 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/20px-od-bel.png   |  Bin 0 -> 886 bytes
 com/aelitis/azureus/ui/images/sb/20px-od-other.png |  Bin 0 -> 692 bytes
 com/aelitis/azureus/ui/images/sb/20px-od-vuze.png  |  Bin 0 -> 695 bytes
 com/aelitis/azureus/ui/images/sb/friends_bg.png    |  Bin 167 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/ic_device_od.png  |  Bin 0 -> 700 bytes
 com/aelitis/azureus/ui/images/sb/ic_rcm.png        |  Bin 0 -> 476 bytes
 .../azureus/ui/images/sb/icon_hide_notch.png       |  Bin 368 -> 0 bytes
 .../azureus/ui/images/sb/icon_hide_notch_over.png  |  Bin 370 -> 0 bytes
 .../azureus/ui/images/sb/icon_show_notch.png       |  Bin 393 -> 0 bytes
 .../azureus/ui/images/sb/icon_show_notch_over.png  |  Bin 389 -> 0 bytes
 .../azureus/ui/images/tb/account_bdr_lft.png       |  Bin 163 -> 0 bytes
 .../azureus/ui/images/tb/account_bdr_lft_small.png |  Bin 138 -> 0 bytes
 .../azureus/ui/images/tb/account_bdr_mid.png       |  Bin 102 -> 0 bytes
 .../azureus/ui/images/tb/account_bdr_mid_small.png |  Bin 97 -> 0 bytes
 .../azureus/ui/images/tb/account_bdr_rgt.png       |  Bin 173 -> 0 bytes
 .../azureus/ui/images/tb/account_bdr_rgt_small.png |  Bin 152 -> 0 bytes
 com/aelitis/azureus/ui/images/tb/ic_share.png      |  Bin 994 -> 0 bytes
 .../azureus/ui/images/tb/ic_share_disabled.png     |  Bin 655 -> 0 bytes
 com/aelitis/azureus/ui/images/thumb_down.png       |  Bin 1520 -> 0 bytes
 com/aelitis/azureus/ui/images/thumb_down_small.png |  Bin 889 -> 0 bytes
 com/aelitis/azureus/ui/images/thumb_up.png         |  Bin 1508 -> 0 bytes
 com/aelitis/azureus/ui/images/thumb_up_small.png   |  Bin 901 -> 0 bytes
 com/aelitis/azureus/ui/skin/SkinConstants.java     |    8 -
 .../azureus/ui/skin/SkinPropertiesImpl.java        |    2 +-
 com/aelitis/azureus/ui/skin/skin3.properties       |    3 +-
 .../azureus/ui/skin/skin3_activities.properties    |   69 -
 .../ui/skin/skin3_buddies_viewer.properties        |   57 -
 .../azureus/ui/skin/skin3_constants.properties     |  105 +-
 .../azureus/ui/skin/skin3_devices_od.properties    |   23 +
 .../ui/skin/skin3_dlg_coreloading.properties       |    9 +-
 .../azureus/ui/skin/skin3_maintabs.properties      |   81 +-
 com/aelitis/azureus/ui/skin/skin3_rcm.properties   |   33 +-
 .../azureus/ui/skin/skin3_sbc_library.properties   |   18 +-
 .../azureus/ui/skin/skin3_sidebar.properties       |   23 +-
 .../ui/skin/skin3_sidebar_friends.properties       |   11 -
 .../azureus/ui/skin/skin3_tab_browse.properties    |    6 +-
 .../ui/skin/skin3_tab_searchresults.properties     |    6 +-
 com/aelitis/azureus/ui/swt/Initializer.java        |   75 +-
 .../azureus/ui/swt/UIConfigDefaultsSWTv3.java      |   56 +-
 .../azureus/ui/swt/browser/BrowserContext.java     |   55 +-
 .../swt/browser/PlatformAuthorizedSenderImpl.java  |  209 --
 .../listener/AbstractBrowserRequestListener.java   |  175 --
 .../listener/AbstractBuddyPageListener.java        |  248 ---
 .../browser/listener/AbstractStatusListener.java   |  119 --
 .../browser/listener/BrowserRpcBuddyListener.java  |   86 -
 .../ui/swt/browser/listener/DisplayListener.java   |   85 +-
 .../browser/listener/IBrowserRequestListener.java  |   67 -
 .../swt/browser/listener/IBuddyPageListener.java   |   73 -
 .../browser/listener/IStatusMessageListener.java   |   35 -
 .../browser/listener/LightBoxBrowserListener.java  |  102 -
 .../listener/LightBoxBrowserRequestListener.java   |   33 -
 .../swt/browser/listener/MetaSearchListener.java   |    2 +
 .../ui/swt/browser/listener/StatusListener.java    |   23 -
 .../ui/swt/browser/listener/TorrentListener.java   |   50 -
 .../swt/browser/listener/publish/LocalHoster.java  |    9 -
 .../browser/listener/publish/PublishListener.java  |  105 -
 .../listener/publish/PublishTransaction.java       |  667 -------
 .../browser/listener/publish/SeedingListener.java  |  332 ---
 .../ui/swt/browser/msg/MessageDispatcherSWT.java   |   21 +-
 .../ui/swt/browser/msg/MessageListener.java        |   30 -
 com/aelitis/azureus/ui/swt/buddy/VuzeBuddySWT.java |   49 -
 .../azureus/ui/swt/buddy/chat/impl/ChatWindow.java |  528 -----
 .../buddy/chat/impl/MessageNotificationWindow.java |  213 --
 .../ui/swt/buddy/impl/VuzeBuddyFakeSWTImpl.java    |   74 -
 .../ui/swt/buddy/impl/VuzeBuddySWTImpl.java        |  154 --
 .../azureus/ui/swt/buddy/impl/VuzeBuddyUtils.java  |   52 -
 .../ui/swt/columns/torrent/ColumnAzProduct.java    |  183 --
 .../ui/swt/columns/torrent/ColumnComplete.java     |   89 -
 .../azureus/ui/swt/columns/torrent/ColumnInfo.java |  160 --
 .../ui/swt/columns/torrent/ColumnIsPrivate.java    |   87 -
 .../ui/swt/columns/torrent/ColumnIsSeeding.java    |   88 -
 .../ui/swt/columns/torrent/ColumnMediaStatus.java  |   69 -
 .../ui/swt/columns/torrent/ColumnMediaThumb.java   |  636 ------
 .../ui/swt/columns/torrent/ColumnProgressETA.java  |  240 ++--
 .../ui/swt/columns/torrent/ColumnQuality.java      |   88 -
 .../azureus/ui/swt/columns/torrent/ColumnRate.java |  783 --------
 .../ui/swt/columns/torrent/ColumnRateUpDown.java   |  320 ---
 .../ui/swt/columns/torrent/ColumnRatingGlobal.java |  340 ----
 .../ui/swt/columns/torrent/ColumnThumbAndName.java |  301 +++
 .../ui/swt/columns/torrent/ColumnThumbnail.java    |   57 +-
 .../ui/swt/columns/torrent/ColumnTitle.java        |  281 ---
 .../ui/swt/columns/torrent/ColumnVideoLength.java  |   74 -
 .../ui/swt/columns/utils/TableColumnCreatorV3.java |  123 +-
 .../vuzeactivity/ColumnActivityActions.java        |  296 +---
 .../columns/vuzeactivity/ColumnActivityAvatar.java |  106 -
 .../columns/vuzeactivity/ColumnActivityNew.java    |    1 +
 .../columns/vuzeactivity/ColumnActivityText.java   |   10 +-
 .../azureus/ui/swt/content/RelatedContentUI.java   |  117 +-
 .../azureus/ui/swt/content/SBC_RCMView.java        |  438 +++--
 .../ui/swt/content/columns/ColumnRC_Created.java   |   68 +
 .../ui/swt/content/columns/ColumnRC_Hash.java      |    3 +-
 .../ui/swt/content/columns/ColumnRC_LastSeen.java  |    2 +-
 .../ui/swt/content/columns/ColumnRC_Level.java     |    2 +-
 .../ui/swt/content/columns/ColumnRC_New.java       |    4 +-
 .../ui/swt/content/columns/ColumnRC_Peers.java     |   67 +
 .../ui/swt/content/columns/ColumnRC_Seeds.java     |   67 +
 .../ui/swt/content/columns/ColumnRC_Title.java     |   12 +-
 .../ui/swt/content/columns/ColumnRC_Tracker.java   |    4 +-
 .../azureus/ui/swt/devices/DeviceManagerUI.java    |  776 ++++++--
 .../azureus/ui/swt/devices/DevicesFTUX.java        |   14 +-
 .../azureus/ui/swt/devices/DevicesODFTUX.java      |  462 +++++
 .../azureus/ui/swt/devices/DevicesWizard.java      |   26 +-
 .../azureus/ui/swt/devices/SBC_DevicesODView.java  |  615 ++++++
 .../azureus/ui/swt/devices/SBC_DevicesView.java    |  132 +-
 .../azureus/ui/swt/devices/TranscodeChooser.java   |   13 +-
 .../ui/swt/devices/add/DeviceTemplateChooser.java  |    6 +-
 .../swt/devices/columns/ColumnOD_Completion.java   |  194 ++
 .../ui/swt/devices/columns/ColumnOD_Name.java      |   58 +
 .../ui/swt/devices/columns/ColumnOD_Remaining.java |   55 +
 .../ui/swt/devices/columns/ColumnOD_Status.java    |   79 +
 .../swt/devices/columns/ColumnTJ_Completion.java   |   23 +-
 .../azureus/ui/swt/imageloader/ImageLoader.java    |  110 +-
 .../azureus/ui/swt/shells/BrowserWindow.java       |   24 +-
 .../ui/swt/shells/LightBoxBrowserWindow.java       |  530 -----
 .../azureus/ui/swt/shells/MessageWindow.java       |  271 ---
 .../azureus/ui/swt/shells/StyledMessageWindow.java |  233 ---
 .../ui/swt/shells/friends/AddFriendsPage.java      |  512 -----
 .../azureus/ui/swt/shells/friends/SharePage.java   |  744 -------
 .../azureus/ui/swt/shells/friends/ShareWizard.java |   28 -
 .../ui/swt/shells/main/DebugMenuHelper.java        |   36 +-
 .../azureus/ui/swt/shells/main/MainMenu.java       |  299 +---
 .../azureus/ui/swt/shells/main/MainWindow.java     |  391 +---
 .../ui/swt/shells/main/UIFunctionsImpl.java        |   36 +-
 .../ui/swt/shells/uiswitcher/UISwitcherWindow.java |   29 +-
 com/aelitis/azureus/ui/swt/skin/SWTSkin.java       |   12 +-
 .../azureus/ui/swt/skin/SWTSkinObjectBasic.java    |   26 +-
 .../azureus/ui/swt/skin/SWTSkinObjectBrowser.java  |   59 +-
 .../azureus/ui/swt/skin/SWTSkinObjectImage.java    |  185 +-
 .../azureus/ui/swt/skin/SWTSkinObjectSash.java     |    2 +-
 com/aelitis/azureus/ui/swt/skin/SWTSkinTabSet.java |   21 -
 com/aelitis/azureus/ui/swt/skin/SWTSkinUtils.java  |    9 +-
 .../swt/subscriptions/SubscriptionListWindow.java  |   23 +-
 .../swt/subscriptions/SubscriptionManagerUI.java   |  224 ++-
 .../subscriptions/SubscriptionSelectedContent.java |   40 +-
 .../ui/swt/subscriptions/SubscriptionWizard.java   |   17 +-
 .../ui/swt/subscriptions/SubscriptionsView.java    |   73 +-
 .../azureus/ui/swt/test/BrowserFlicker.java        |  110 -
 .../azureus/ui/swt/test/ImageOverImage.java        |   92 -
 .../azureus/ui/swt/test/TorrentThumbnail.java      |  151 --
 .../ui/swt/tests/TestPlatformMessenger.java        |  135 --
 .../swt/utils/ContentNetworkUIManagerWindow.java   |  193 --
 com/aelitis/azureus/ui/swt/utils/ImageResizer.java |   56 +-
 com/aelitis/azureus/ui/swt/utils/PublishUtils.java |   19 -
 .../azureus/ui/swt/utils/SWTLoginUtils.java        |  161 --
 .../azureus/ui/swt/utils/TorrentUIUtilsV3.java     |   54 +-
 .../azureus/ui/swt/utils/UIMagnetHandler.java      |   20 +-
 .../azureus/ui/swt/views/skin/AvatarWidget.java    | 1658 ---------------
 com/aelitis/azureus/ui/swt/views/skin/Browse.java  |   22 +-
 .../azureus/ui/swt/views/skin/BuddiesViewer.java   |  991 ---------
 .../azureus/ui/swt/views/skin/FriendsToolbar.java  |  907 ---------
 .../ui/swt/views/skin/MyTorrentsView_Big.java      |    5 +-
 com/aelitis/azureus/ui/swt/views/skin/Publish.java |   55 -
 .../ui/swt/views/skin/SBC_ActivityTableView.java   |  126 +-
 .../ui/swt/views/skin/SBC_LibraryTableView.java    |   76 +-
 .../azureus/ui/swt/views/skin/SBC_LibraryView.java |   49 +-
 .../ui/swt/views/skin/SearchResultsTabArea.java    |   40 +
 .../azureus/ui/swt/views/skin/ToolBarView.java     |   47 +-
 .../ui/swt/views/skin/TorrentListViewsUtils.java   |  401 ++--
 .../azureus/ui/swt/views/skin/UserAreaUtils.java   |  407 ----
 .../azureus/ui/swt/views/skin/VuzeShareUtils.java  |  365 ----
 .../azureus/ui/swt/views/skin/WelcomeView.java     |   11 +-
 .../azureus/ui/swt/views/skin/sidebar/SideBar.java |  199 ++-
 .../ui/swt/views/skin/sidebar/SideBarEntrySWT.java |    2 +-
 .../skin/sidebar/SideBarVitalityImageSWT.java      |    5 +-
 .../ui/swt/views/skin/widgets/FriendsList.java     |  547 -----
 com/aelitis/azureus/util/AzpdFileAccess.java       |  160 --
 com/aelitis/azureus/util/ConstantsVuze.java        |    6 -
 com/aelitis/azureus/util/DCAdManager.java          | 1072 ----------
 com/aelitis/azureus/util/DataSourceUtils.java      |   31 +-
 com/aelitis/azureus/util/DownloadUtils.java        |    7 +
 com/aelitis/azureus/util/FAQTopics.java            |    9 -
 com/aelitis/azureus/util/ILoginInfoListener.java   |   13 -
 .../azureus/util/InitialisationFunctions.java      |   15 +-
 .../azureus/util/JSFunctionParametersParser.java   |  104 -
 com/aelitis/azureus/util/LoginInfoManager.java     |  202 --
 com/aelitis/azureus/util/NavigationHelper.java     |    8 -
 com/aelitis/azureus/util/PlayUtils.java            |   17 +-
 com/aelitis/azureus/util/PublishUtils.java         |  165 --
 com/aelitis/net/magneturi/MagnetURIHandler.java    |   19 +
 .../net/magneturi/impl/MagnetURIHandlerImpl.java   |   91 +-
 .../natpmp/upnp/impl/NatPMPUPnPRootDeviceImpl.java |    7 +
 com/aelitis/net/upnp/UPnP.java                     |    6 +
 com/aelitis/net/upnp/UPnPRootDevice.java           |    4 +
 com/aelitis/net/upnp/UPnPSSDP.java                 |    1 -
 com/aelitis/net/upnp/impl/UPnPImpl.java            |  362 +++--
 .../net/upnp/impl/device/UPnPRootDeviceImpl.java   |   32 +-
 .../impl/services/UPnPSSOfflineDownloaderImpl.java |  361 ++++
 .../net/upnp/impl/services/UPnPServiceImpl.java    |    4 +
 com/aelitis/net/upnp/impl/ssdp/SSDPCore.java       |    4 +-
 com/aelitis/net/upnp/impl/ssdp/SSDPIGDImpl.java    |    2 +-
 .../net/upnp/services/UPnPOfflineDownloader.java   |   84 +
 debian/README.source                               |   15 -
 debian/azureus.desktop                             |    2 +-
 debian/changelog                                   |   15 +
 debian/control                                     |    3 +-
 debian/docs                                        |    1 -
 debian/patches/debian/speedtest.diff               |    2 +-
 debian/patches/debian/update-disable.diff          |   12 +-
 debian/patches/fixes/encoding.diff                 |    4 +-
 debian/patches/fixes/multi-announce-deadlock.diff  |   60 -
 debian/patches/fixes/multiuser.diff                |   29 +-
 debian/patches/fixes/platform.diff                 |   26 +-
 debian/patches/fixes/sunsecurity.diff              |   46 +-
 debian/patches/fixes/utf8-encoding.diff            |  391 ----
 debian/patches/series                              |    2 -
 debian/rules                                       |    1 -
 debian/source/format                               |    1 +
 .../core3/config/COConfigurationManager.java       |    8 +-
 .../core3/config/impl/ConfigurationDefaults.java   |    9 +-
 org/gudy/azureus2/core3/disk/DiskManager.java      |    8 +
 .../azureus2/core3/disk/impl/DiskManagerImpl.java  |   14 +-
 .../core3/disk/impl/access/impl/DMCheckerImpl.java |   29 +-
 .../impl/piecemapper/impl/PieceMapperImpl.java     |   55 +-
 .../azureus2/core3/download/DownloadManager.java   |    7 +
 .../core3/download/DownloadManagerState.java       |    5 +
 .../download/impl/DownloadManagerController.java   |    7 +-
 .../core3/download/impl/DownloadManagerImpl.java   |   10 +-
 .../download/impl/DownloadManagerStateImpl.java    |   44 +-
 .../core3/global/impl/GlobalManagerImpl.java       |   26 +
 .../azureus2/core3/internat/LocaleTorrentUtil.java |    6 +
 org/gudy/azureus2/core3/internat/MessageText.java  |   20 +-
 org/gudy/azureus2/core3/peer/PEPeer.java           |    7 +
 .../azureus2/core3/peer/PEPeerManagerStats.java    |    6 +
 .../core3/peer/impl/PEPeerManagerStatsImpl.java    |   50 +-
 .../azureus2/core3/peer/impl/PEPeerTransport.java  |    3 +-
 .../core3/peer/impl/control/PEPeerControlImpl.java |  114 +-
 .../impl/transport/PEPeerTransportProtocol.java    |   23 +-
 .../core3/stats/impl/StatsWriterPeriodicImpl.java  |  176 +--
 .../stats/transfer/impl/OverallStatsImpl.java      |   70 +-
 org/gudy/azureus2/core3/torrent/TOTorrent.java     |    8 +-
 .../torrent/impl/TOTorrentDeserialiseImpl.java     |   47 +-
 .../core3/torrent/impl/TOTorrentFileImpl.java      |  116 +-
 .../azureus2/core3/torrent/impl/TOTorrentImpl.java |   53 +-
 .../impl/TorrentDownloaderImpl.java                |   61 +-
 .../client/TRTrackerScraperClientResolver.java     |   10 +
 .../tracker/client/impl/TRTrackerScraperImpl.java  |    6 +
 .../client/impl/bt/TRTrackerBTAnnouncerImpl.java   |   78 +-
 .../tracker/client/impl/bt/TrackerChecker.java     |   86 +-
 .../tracker/client/impl/bt/TrackerStatus.java      |   23 +-
 .../client/impl/dht/TRTrackerDHTScraperImpl.java   |   67 +-
 .../core3/tracker/host/impl/TRHostConfigImpl.java  |   19 +-
 .../tracker/host/impl/TRHostExternalTorrent.java   |    6 +
 .../impl/tcp/nonblocking/TRNonBlockingServer.java  |   24 +-
 .../core3/tracker/util/TRTrackerUtils.java         |   48 +-
 org/gudy/azureus2/core3/util/AEDiagnostics.java    |   30 +-
 .../azureus2/core3/util/AEDiagnosticsLogger.java   |   12 +-
 .../azureus2/core3/util/AERunnableBoolean.java     |    2 +-
 org/gudy/azureus2/core3/util/AEThread2.java        |    4 +-
 org/gudy/azureus2/core3/util/AddressUtils.java     |   61 +-
 org/gudy/azureus2/core3/util/Average.java          |    2 +-
 org/gudy/azureus2/core3/util/BDecoder.java         |  114 +-
 org/gudy/azureus2/core3/util/BEncodableObject.java |   36 +
 org/gudy/azureus2/core3/util/BEncoder.java         |    6 +-
 org/gudy/azureus2/core3/util/ByteFormatter.java    |   12 +
 org/gudy/azureus2/core3/util/Constants.java        |   67 +-
 org/gudy/azureus2/core3/util/Debug.java            |    3 +
 .../azureus2/core3/util/DisplayFormatters.java     |   67 +-
 org/gudy/azureus2/core3/util/FileUtil.java         |  180 ++-
 org/gudy/azureus2/core3/util/ListenerManager.java  |    6 +-
 org/gudy/azureus2/core3/util/StringInterner.java   |  437 +++--
 org/gudy/azureus2/core3/util/SystemTime.java       |   74 +-
 org/gudy/azureus2/core3/util/TorrentUtils.java     |    7 +
 .../azureus2/internat/MessagesBundle.properties    |  247 ++--
 .../internat/MessagesBundle_de_DE.properties       |  159 +-
 .../internat/MessagesBundle_fi_FI.properties       |  146 +-
 .../internat/MessagesBundle_hu_HU.properties       |    4 +-
 .../internat/MessagesBundle_it_IT.properties       |  565 +++---
 .../internat/MessagesBundle_ja_JP.properties       |    6 +-
 .../internat/MessagesBundle_li_NL.properties       |    4 +-
 .../internat/MessagesBundle_ro_RO.properties       |   48 +-
 .../internat/MessagesBundle_uk_UA.properties       | 1463 ++++++++------
 .../platform/macosx/NativeInvocationBridge.java    |   44 +-
 .../platform/macosx/PlatformManagerImpl.java       |   15 +-
 .../macosx/PlatformManagerUpdateChecker.java       |   19 +-
 .../platform/macosx/access/jnilib/OSXAccess.java   |   37 +-
 .../platform/unix/PlatformManagerUnixPlugin.java   |   48 +-
 .../platform/win32/PlatformManagerImpl.java        |    8 +-
 .../platform/win32/access/impl/Release/aereg64.dll |  Bin 0 -> 85504 bytes
 org/gudy/azureus2/plugins/PluginEvent.java         |    6 +
 .../azureus2/plugins/PluginManagerDefaults.java    |    2 +
 org/gudy/azureus2/plugins/PluginState.java         |    5 +
 .../azureus2/plugins/ddb/DistributedDatabase.java  |    7 +
 .../plugins/ddb/DistributedDatabaseContact.java    |    7 +
 org/gudy/azureus2/plugins/download/Download.java   |    8 +
 .../plugins/sharing/ShareManagerListener.java      |    3 +-
 org/gudy/azureus2/plugins/ui/UIInputReceiver.java  |   13 +
 .../plugins/ui/UIInputReceiverListener.java        |    6 +
 org/gudy/azureus2/plugins/utils/Utilities.java     |   36 +
 .../plugins/utils/subscriptions/Subscription.java  |   35 +
 .../utils/subscriptions/SubscriptionException.java |   42 +
 .../utils/subscriptions/SubscriptionManager.java   |   29 +
 .../utils/subscriptions/SubscriptionResult.java    |   40 +
 .../pluginsimpl/local/PluginCoreUtils.java         |    1 -
 .../pluginsimpl/local/PluginInitializer.java       |   42 +
 .../pluginsimpl/local/PluginStateImpl.java         |    6 +
 .../pluginsimpl/local/ddb/DDBaseContactImpl.java   |   82 +
 .../azureus2/pluginsimpl/local/ddb/DDBaseImpl.java |   48 +-
 .../pluginsimpl/local/download/DownloadImpl.java   |    6 +
 .../local/download/DownloadManagerImpl.java        |   49 +-
 .../local/peers/PeerForeignDelegate.java           |   15 +-
 .../local/sharing/ShareManagerImpl.java            |   57 +-
 .../sharing/ShareResourceDirContentsImpl.java      |    2 +-
 .../local/sharing/ShareResourceFileOrDirImpl.java  |    6 +-
 .../local/sharing/ShareResourceImpl.java           |   12 +-
 .../local/sharing/test/ShareTester.java            |    5 +-
 org/gudy/azureus2/pluginsimpl/local/test/Test.java |   30 +-
 .../local/tracker/TrackerWebPageResponseImpl.java  |   22 +-
 .../local/ui/AbstractUIInputReceiver.java          |   18 +
 .../local/ui/components/UITextAreaImpl.java        |  217 ++-
 .../local/ui/model/BasicPluginConfigModelImpl.java |    9 +-
 .../pluginsimpl/local/utils/UtilitiesImpl.java     |  188 ++
 .../local/utils/resourcedownloader/Test.java       |    4 +-
 .../local/utils/xml/rss/RSSChannelImpl.java        |   23 +-
 .../local/utils/xml/rss/RSSItemImpl.java           |   28 +-
 .../simpleparser/SimpleXMLParserDocumentImpl.java  |   45 +-
 .../pluginsimpl/remote/download/RPDownload.java    |    8 +
 .../update/sf/impl2/SFPluginDetailsLoaderImpl.java |    2 +
 org/gudy/azureus2/ui/icons/a128.jpg                |  Bin 6560 -> 0 bytes
 org/gudy/azureus2/ui/icons/a128.png                |  Bin 0 -> 9310 bytes
 org/gudy/azureus2/ui/icons/icons.properties        |   13 +-
 org/gudy/azureus2/ui/icons/rcm.png                 |  Bin 0 -> 544 bytes
 org/gudy/azureus2/ui/jws/Main.java                 |  198 --
 org/gudy/azureus2/ui/swt/CategoryAdderWindow.java  |  128 +-
 org/gudy/azureus2/ui/swt/IconBar.java              |   22 +-
 org/gudy/azureus2/ui/swt/ImageRepository.java      |   68 +-
 org/gudy/azureus2/ui/swt/MessageBoxWindow.java     |  249 ---
 org/gudy/azureus2/ui/swt/Messages.java             |   11 +-
 org/gudy/azureus2/ui/swt/OpenTorrentWindow.java    |  141 +-
 org/gudy/azureus2/ui/swt/PasswordWindow.java       |    3 +-
 org/gudy/azureus2/ui/swt/PropertiesWindow.java     |    5 +-
 .../azureus2/ui/swt/SimpleTextEntryWindow.java     |   36 +-
 org/gudy/azureus2/ui/swt/TorrentUtil.java          |  303 ++--
 org/gudy/azureus2/ui/swt/UIConfigDefaultsSWT.java  |    6 +-
 org/gudy/azureus2/ui/swt/UIExitUtilsSWT.java       |   20 +-
 org/gudy/azureus2/ui/swt/UISwitcherUtil.java       |  248 +--
 org/gudy/azureus2/ui/swt/Utils.java                |  459 ++---
 .../ui/swt/associations/AssociationChecker.java    |    3 +-
 .../azureus2/ui/swt/auth/AuthenticatorWindow.java  |    3 +-
 .../ui/swt/auth/CertificateCreatorWindow.java      |    3 +-
 .../ui/swt/auth/CertificateTrustWindow.java        |    3 +-
 org/gudy/azureus2/ui/swt/auth/CryptoWindow.java    |   15 +-
 .../swt/components/BufferedGraphicTableItem1.java  |   43 +-
 .../ui/swt/components/BufferedTableItemImpl.java   |   60 +-
 .../ui/swt/components/BufferedTruncatedLabel.java  |    2 +-
 .../ui/swt/components/shell/LightBoxShell.java     |  503 -----
 .../ui/swt/components/shell/ShellFactory.java      |   28 +-
 .../ui/swt/components/shell/StyledShell.java       |  649 ------
 .../ui/swt/components/widgets/BubbleButton.java    |   93 -
 .../azureus2/ui/swt/components/widgets/Inset.java  |   20 -
 .../swt/components/widgets/PaginationWidget.java   |  226 ---
 .../ui/swt/components/widgets/SkinButton.java      |  379 ----
 .../ui/swt/components/widgets/SkinLinkLabel.java   |   74 -
 .../ui/swt/config/StringListParameter.java         |    5 +
 .../azureus2/ui/swt/config/StringParameter.java    |    6 +
 .../ui/swt/config/generic/GenericIntParameter.java |    4 +-
 .../ui/swt/config/wizard/ConfigureWizard.java      |   17 +-
 .../azureus2/ui/swt/debug/UIDebugGenerator.java    |   34 +-
 .../azureus2/ui/swt/donations/DonationWindow.java  |   36 +-
 org/gudy/azureus2/ui/swt/help/AboutWindow.java     |   69 +-
 org/gudy/azureus2/ui/swt/mainwindow/Colors.java    |    2 +
 .../azureus2/ui/swt/mainwindow/IMenuConstants.java |   13 +-
 .../azureus2/ui/swt/mainwindow/Initializer.java    |    2 +-
 org/gudy/azureus2/ui/swt/mainwindow/MainMenu.java  |    6 +-
 .../azureus2/ui/swt/mainwindow/MainStatusBar.java  |   96 +-
 .../azureus2/ui/swt/mainwindow/MainWindow.java     |   47 +-
 .../azureus2/ui/swt/mainwindow/MenuFactory.java    |   41 +-
 org/gudy/azureus2/ui/swt/mainwindow/SWTThread.java |  219 +-
 .../ui/swt/mainwindow/SelectableSpeedMenu.java     |   80 +-
 .../ui/swt/mainwindow/UIFunctionsImpl.java         |   28 +-
 .../azureus2/ui/swt/maketorrent/ModePanel.java     |    4 +-
 .../ui/swt/maketorrent/WebSeedsEditor.java         |   10 +-
 org/gudy/azureus2/ui/swt/nat/NatTestWindow.java    |    2 +-
 .../ui/swt/networks/SWTNetworkSelection.java       |   15 +-
 org/gudy/azureus2/ui/swt/nico/testOSX.java         |  132 --
 org/gudy/azureus2/ui/swt/osx/CarbonUIEnhancer.java |   23 +-
 org/gudy/azureus2/ui/swt/osx/CocoaUIEnhancer.java  |  844 ++++++++
 .../azureus2/ui/swt/plugins/UISWTInstance.java     |   12 +
 .../ui/swt/pluginsimpl/BasicPluginConfigImpl.java  |   15 +-
 .../azureus2/ui/swt/pluginsimpl/UIMessageImpl.java |   27 +-
 .../ui/swt/pluginsimpl/UISWTInstanceImpl.java      |   79 +-
 .../ui/swt/pluginsimpl/UISWTStatusEntryImpl.java   |   18 +
 .../ui/swt/sharing/progress/ProgressWindow.java    |    5 +-
 .../azureus2/ui/swt/shells/AdvRenameWindow.java    |  243 +++
 org/gudy/azureus2/ui/swt/shells/BrowserShell.java  |    7 +-
 org/gudy/azureus2/ui/swt/shells/CoreWaiterSWT.java |   29 +-
 .../azureus2/ui/swt/shells/GCStringPrinter.java    |  104 +-
 .../azureus2/ui/swt/shells/MessageBoxShell.java    |  904 ++++------
 .../azureus2/ui/swt/shells/MessageSlideShell.java  |   44 +-
 .../azureus2/ui/swt/shells/MultipageWizard.java    |   22 +-
 .../ui/swt/shells/SimpleBrowserWindow.java         |   32 +-
 .../azureus2/ui/swt/snippets/OnTopProblem.java     |  136 --
 .../ui/swt/snippets/TableWith0sizedColumn.java     |   99 -
 .../azureus2/ui/swt/update/FullUpdateWindow.java   |   11 +-
 org/gudy/azureus2/ui/swt/update/UpdateMonitor.java |   47 +-
 org/gudy/azureus2/ui/swt/update/UpdateWindow.java  |   18 +-
 .../azureus2/ui/swt/updater2/SWTVersionGetter.java |   98 +-
 org/gudy/azureus2/ui/swt/views/FilesView.java      |   99 +-
 org/gudy/azureus2/ui/swt/views/GeneralView.java    |   15 +-
 org/gudy/azureus2/ui/swt/views/ManagerView.java    |    7 +-
 org/gudy/azureus2/ui/swt/views/MySharesView.java   |   14 +-
 org/gudy/azureus2/ui/swt/views/MyTorrentsView.java |  634 +++----
 org/gudy/azureus2/ui/swt/views/MyTrackerView.java  |   10 +-
 org/gudy/azureus2/ui/swt/views/PeerSuperView.java  |   16 +-
 org/gudy/azureus2/ui/swt/views/PeersView.java      |    9 +-
 .../ui/swt/views/PieceDistributionView.java        |   48 +-
 org/gudy/azureus2/ui/swt/views/PiecesView.java     |   10 +-
 .../azureus2/ui/swt/views/TorrentOptionsView.java  |    8 -
 .../views/clientstats/ClientStatsDataSource.java   |   48 +
 .../swt/views/clientstats/ClientStatsOverall.java  |   50 +
 .../ui/swt/views/clientstats/ClientStatsView.java  |  580 ++++++
 .../ui/swt/views/clientstats/ColumnCS_Count.java   |   27 +
 .../swt/views/clientstats/ColumnCS_Discarded.java  |   30 +
 .../ui/swt/views/clientstats/ColumnCS_Name.java    |   27 +
 .../ui/swt/views/clientstats/ColumnCS_Pct.java     |   32 +
 .../swt/views/clientstats/ColumnCS_Received.java   |   30 +
 .../ui/swt/views/clientstats/ColumnCS_Sent.java    |   30 +
 .../views/columnsetup/TableColumnSetupWindow.java  |   97 +-
 .../configsections/ConfigSectionConnection.java    |    5 -
 .../ConfigSectionConnectionAdvanced.java           |   19 +-
 .../views/configsections/ConfigSectionFile.java    |    2 -
 .../ConfigSectionFilePerformance.java              |    6 -
 .../configsections/ConfigSectionIPFilter.java      |    5 +-
 .../configsections/ConfigSectionInterface.java     |   46 +-
 .../ConfigSectionInterfaceAlerts.java              |    1 -
 .../ConfigSectionInterfaceDisplay.java             |   49 +-
 .../ConfigSectionInterfaceStart.java               |   31 +-
 .../views/configsections/ConfigSectionPlugins.java |   18 +-
 .../configsections/ConfigSectionSecurity.java      |   97 +-
 .../views/configsections/ConfigSectionSharing.java |    1 -
 .../configsections/ConfigSectionTrackerClient.java |    6 +-
 .../configsections/ConfigSectionTrackerServer.java |   24 +-
 .../configsections/ConfigSectionTransfer.java      |   10 -
 .../configsections/ConfigSectionTransferLAN.java   |    2 -
 .../azureus2/ui/swt/views/file/FileInfoView.java   |   49 +-
 .../azureus2/ui/swt/views/peer/PeerInfoView.java   |   35 +-
 .../azureus2/ui/swt/views/piece/PieceInfoView.java |    6 +-
 org/gudy/azureus2/ui/swt/views/stats/DHTView.java  |    6 +-
 .../ui/swt/views/stats/TrackerStatsView.java       |   44 +
 .../ui/swt/views/stats/TransferStatsView.java      |   28 +-
 .../ui/swt/views/table/TableViewFilterCheck.java   |   32 +
 .../azureus2/ui/swt/views/table/TableViewSWT.java  |   33 +
 .../ui/swt/views/table/impl/TableCellImpl.java     |   43 +-
 .../ui/swt/views/table/impl/TableViewSWTImpl.java  |  901 ++++++---
 .../ui/swt/views/table/impl/TableViewTab.java      |   91 +-
 .../swt/views/table/utils/TableColumnCreator.java  |   19 +-
 .../swt/views/table/utils/TableColumnManager.java  |   66 +-
 .../ui/swt/views/tableitems/ColumnDateSizer.java   |    7 +-
 .../swt/views/tableitems/files/FirstPieceItem.java |   18 +-
 .../ui/swt/views/tableitems/files/NameItem.java    |    8 +-
 .../ui/swt/views/tableitems/files/PercentItem.java |    5 +-
 .../tableitems/mytorrents/CommentIconItem.java     |   17 +-
 .../swt/views/tableitems/mytorrents/NameItem.java  |   23 +-
 .../azureus2/ui/swt/views/utils/ManagerUtils.java  |   80 +-
 .../ui/swt/views/utils/VerticalAligner.java        |   70 -
 .../azureus2/ui/swt/welcome/WelcomeWindow.java     |  157 +-
 .../azureus2/ui/swt/win32/Win32UIEnhancer.java     |  305 ++-
 org/gudy/azureus2/ui/swt/wizard/Wizard.java        |   15 +-
 org/gudy/azureus2/ui/systray/SystemTraySWT.java    |  129 +-
 org/gudy/azureus2/ui/webplugin/WebPlugin.java      |  291 +++-
 org/gudy/azureus2/update/CorePatchLevel.java       |    4 +-
 org/gudy/azureus2/update/CoreUpdateChecker.java    |    4 +-
 738 files changed, 31985 insertions(+), 40312 deletions(-)

diff --git a/ChangeLog.txt b/ChangeLog.txt
index 40871e5..9e71e84 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,6 +1,82 @@
 VUZE CHANGELOG
 -----------------
 
+2009.11.11 | Vuze 4.3.0.0
+
+FEATURE: Core | Added support for UPnP based offline-downloader services [Parg]
+FEATURE: Core | Obfuscated lookups for the DHT to prevent leakage of key values during lookup stage [Parg]
+FEATURE: Core | Support copying of .mp3 and .wma files to PSP [Parg]
+FEATURE: Core | Implementation of a piece-reordering file manager [Parg]
+FEATURE: Core | DHT replication controls [Parg]
+FEATURE: Core | Initial pairing support [Parg]
+FEATURE: Core | Parse seed/leecher values from subscription text if found [Parg]
+FEATURE: Core | Added bloom-filter persistence [Parg]
+FEATURE: Core | Support ".utf-8" suffix for keys in .torrent files [TuxPaper] 
+FEATURE: Plug | Added download-flags to Download object [Parg]
+FEATURE: Plug | Plugin access to subscriptions [Parg]
+FEATURE: Plug | Added verified plugins [Parg]
+FEATURE: UIvz | Added "Reset Columns" ability to some views (in Column Setup) [TuxPaper]
+FEATURE: UIvz | Client now opens to last used static view, or Library by default [TuxPaper]
+FEATURE: UI   | Support for switching between carbon and cocoa on OSX [Parg]
+FEATURE: UI   | Generic filter support for our tables [Parg]
+FEATURE: UI   | Support for showing real SI values rather than just changing units displayed [Parg]
+FEATURE: UI   | Advanced menu option for editing http seeds [Parg]
+
+CHANGE: Core  | Remove replicate-on-join from DHT as causing excessive key storage [Parg]
+CHANGE: Core  | Roll up subscription warnings when not expanded [Parg]
+CHANGE: Core  | Improved IPv6-handshaking and reconnects with other clients (see http://www.azureuswiki.com/index.php/IPv6_compatibility for supported systems) [The 8472]
+CHANGE: Core  | Switch back to k-select on OSX [Nolar]
+CHANGE: Core  | Reduce CPU used for node-id calculation via MRU cache [Parg]
+CHANGE: Core  | Remove LAN transfer totals from data reported to tracker [Parg]
+CHANGE: Core  | Implemented port restriction for DHT node id generation [Parg]
+CHANGE: Core  | Reduce memory/CPU by disabling the largely unused Vivaldi V2 impl [Parg]
+CHANGE: Core  | Reduce DHT load by removing network-position derived tracking targets [Parg]
+CHANGE: Core  | Back off the initial DHT seeding [Parg]
+CHANGE: Core  | Cache redirects for http seeds
+CHANGE: Core  | Use async keep-alive test to reduce thread creation on magnet download [Parg]
+CHANGE: Core  | Change defaults for I2P and Tor networks to fase [Parg]
+CHANGE: Core  | Support http seeds that don't support partial content [Parg]
+CHANGE: Core  | Added option to disable TiVo support completely [Parg]
+CHANGE: Core  | Support RSS feeds with incorrect 'summary' instead of 'description' entries [Parg]
+CHANGE: Core  | Support trackers that returned gzipped torrents even when not asked to [Parg]
+CHANGE: Core  | Migrate away from system-managed private keys [Parg]
+CHANGE: Core  | Support meta-search incremental result injection [Parg]
+CHANGE: Core  | Use cached scrape values on startup for DHT torrents to reduce thrashing [Parg]
+CHANGE: Core  | Switch version check to use HTTP by default [Parg]
+CHANGE: Core  | Resource resources by grabbing piecemap once during piece pick operation [Parg]
+CHANGE: Core  | Reduce cost of handling DHT store operations [Parg]
+CHANGE: Core  | Remove 'force write' option from random access file access [Parg]
+CHANGE: Core  | Move a few things to use the less costly stepped-monotime method [Parg]
+CHANGE: Core  | Re-use http connections when messaging the platform [Parg]
+CHANGE: Core  | Don't write diagnostic files to disk by default [Parg]
+CHANGE: Core  | Reduce small scratch file creation on startup [Parg]
+CHANGE: Core  | Don't write tables.config every start [Parg]
+CHANGE: Core  | If we don't have hosted content, don't write the config file [Parg]
+CHANGE: Core  | Potentially less Tracker Announces for those trackers not supplying "min interval" [TuxPaper]
+CHANGE: Plug  | Reduce frequency of UPnP device specification download attempts [Parg]
+CHANGE: UIvz  | Removed Login and Friends, Content Networks menu [TuxPaper]
+CHANGE: UI    | Order files in file view by torrent index if piece numbers same [Parg]
+CHANGE: UI    | Pulled out the RSS feed generation for devices and put into common location [Parg]
+CHANGE: UI    | Allows addition of http seeds to decentralised torrents [Parg]
+CHANGE: UI    | Make regex matching mode more obvious [Parg]
+CHANGE: UI    | Better "Associated Application" icon logic [TuxPaper]
+CHANGE: UI    | (OSX) Switch to SWT for Cocoa Framework [TuxPaper]
+
+BUGFIX: Core  | Don't reset manually selected Vuze meta search templates on load [Parg]
+BUGFIX: Core  | Removed 'watched' tag from torrents on import [Parg]
+BUGFIX: Core  | index-out-of-bounds fix when global peer limit reached [Parg]
+BUGFIX: Core  | Fix incorrect sync of scrape hashes [Parg]
+BUGFIX: Core  | Prevent unwanted selection of in-error subscriptions [Parg]
+BUGFIX: Plug  | Force UPnP operations not to use socks/http proxy when defined [Parg]
+BUGFIX: UI    | Fixed case where Open Torrents Window might erase existing files [TuxPaper]
+BUGFIX: UI    | Fixed context menus sometimes hanging client on Windows 7 [TuxPaper]
+BUGFIX: UI    | Fix missing icons for pause/resume in all-transfers bar [Parg]
+BUGFIX: UI    | Fix invalid thread access in parameter change logic [Parg]
+BUGFIX: UI    | Fix progress-dialog feedback for magnet downloads [Parg]
+BUGFIX: UI    | Fix cases on OSX where a modal dialog box ended up under main window [TuxPaper]
+
+
+
 2009.08.27 | Vuze 4.2.0.8
 
 FEATURE: Core | Drive Detection for Devices for OSX (for PSP devices) [TuxPaper]
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesBuddyInvited.java b/com/aelitis/azureus/activities/VuzeActivitiesBuddyInvited.java
deleted file mode 100644
index 068f064..0000000
--- a/com/aelitis/azureus/activities/VuzeActivitiesBuddyInvited.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * Created on Jun 6, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.activities;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.SystemTime;
-
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-
-/**
- * @author TuxPaper
- * @created Jun 6, 2008
- *
- */
-public class VuzeActivitiesBuddyInvited
-	extends VuzeActivitiesEntry
-{
-
-	public VuzeActivitiesBuddyInvited(List displayNames) {
-		String names = "";
-		for (Iterator iter = displayNames.iterator(); iter.hasNext();) {
-			String[] name = (String[]) iter.next();
-			if (names.length() > 0) {
-				names += ", ";
-			}
-			if (name[1] != null && name[1].length() > 0) {
-				names += VuzeBuddyManager.generateBuddyAHREF(name[0], name[1],
-						VuzeActivitiesConstants.TYPEID_BUDDYINVITED);
-			} else {
-				names += name[0];
-			}
-		}
-		String id = "v3.activity.buddy-invited";
-		if (displayNames.size() > 1) {
-			id += ".multi";
-		}
-
-		String text = MessageText.getString(id, new String[] {
-			names
-		});
-
-		setText(text);
-		setTypeID(VuzeActivitiesConstants.TYPEID_BUDDYINVITED, true);
-		setID(VuzeActivitiesConstants.TYPEID_BUDDYINVITED + "-"
-				+ SystemTime.getCurrentTime());
-	}
-}
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesConstants.java b/com/aelitis/azureus/activities/VuzeActivitiesConstants.java
index 2762361..934259f 100644
--- a/com/aelitis/azureus/activities/VuzeActivitiesConstants.java
+++ b/com/aelitis/azureus/activities/VuzeActivitiesConstants.java
@@ -18,10 +18,6 @@
 
 package com.aelitis.azureus.activities;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import org.gudy.azureus2.core3.internat.MessageText;
 
 /**
  * @author TuxPaper
@@ -30,80 +26,11 @@ import org.gudy.azureus2.core3.internat.MessageText;
  */
 public class VuzeActivitiesConstants
 {
-	public static final String TYPEID_RATING_REMINDER = "Rating-Reminder";
-
 	public static final String TYPEID_HEADER = "Header";
 
 	public static final String TYPEID_VUZENEWS = "VUZE_NEWS_ITEM";
 
-	public static final String TYPEID_BUDDYLINKUP = "buddy-new";
-
-	public static final String TYPEID_BUDDYREQUEST = "buddy-request";
-
-	public static final String TYPEID_BUDDYSHARE = "buddy-share";
-
 	public static final String TYPEID_CHANNEL_ANNOUNCE = "CHANNEL_ANNOUNCE";
 
 	public static final String TYPEID_CONTENT_PROMO = "CONTENT_PROMO";
-
-	public static final String TYPEID_BUDDYINVITED = "buddy-invited";
-
-	public static final int SORT_DATE = 0;
-
-	public static final int SORT_TYPE = 1;
-
-	public static final Map SORT_TYPE_ORDER = new HashMap();
-
-	public static VuzeActivitiesEntry[] HEADERS_SORTBY_TYPE;
-
-	static {
-		int pos = 0;
-		SORT_TYPE_ORDER.put(TYPEID_BUDDYREQUEST, new Long(pos));
-		pos++;
-		SORT_TYPE_ORDER.put(TYPEID_BUDDYINVITED, new Long(pos));
-		pos++;
-		SORT_TYPE_ORDER.put(TYPEID_BUDDYLINKUP, new Long(pos));
-		pos++;
-
-		SORT_TYPE_ORDER.put(TYPEID_BUDDYSHARE, new Long(pos));
-		pos++;
-
-		//SORT_TYPE_ORDER.put(TYPEID_DL_ADDED, new Long(pos));
-		//SORT_TYPE_ORDER.put(TYPEID_DL_COMPLETE, new Long(pos));
-		//SORT_TYPE_ORDER.put(TYPEID_DL_REMOVE, new Long(pos));
-		//pos++;
-
-		SORT_TYPE_ORDER.put(TYPEID_RATING_REMINDER, new Long(pos));
-		pos++;
-
-		SORT_TYPE_ORDER.put(TYPEID_VUZENEWS, new Long(pos));
-		SORT_TYPE_ORDER.put(TYPEID_CHANNEL_ANNOUNCE, new Long(pos));
-		SORT_TYPE_ORDER.put(TYPEID_CONTENT_PROMO, new Long(pos));
-		pos++;
-
-		HEADERS_SORTBY_TYPE = new VuzeActivitiesEntry[] {
-			new VuzeActivitiesEntry(0,
-					MessageText.getString("v3.activity.header.friend.requests.foryou"),
-					null, TYPEID_BUDDYREQUEST, TYPEID_HEADER, null),
-			new VuzeActivitiesEntry(0,
-					MessageText.getString("v3.activity.header.friend.requests.fromyou"),
-					null, TYPEID_BUDDYINVITED, TYPEID_HEADER, null),
-			new VuzeActivitiesEntry(0,
-					MessageText.getString("v3.activity.header.friend.requests.accepted"),
-					null, TYPEID_BUDDYLINKUP, TYPEID_HEADER, null),
-			new VuzeActivitiesEntry(0,
-					MessageText.getString("v3.activity.header.share.requests"), null,
-					TYPEID_BUDDYSHARE, TYPEID_HEADER, null),
-			/*new VuzeActivitiesEntry(0,
-					MessageText.getString("v3.activity.header.downloads"), null,
-					TYPEID_DL_ADDED, TYPEID_HEADER, null),*/
-			new VuzeActivitiesEntry(0,
-					MessageText.getString("v3.activity.header.rating.reminders"), null,
-					TYPEID_RATING_REMINDER, TYPEID_HEADER, null),
-			new VuzeActivitiesEntry(0,
-					MessageText.getString("v3.activity.header.vuze.news"), null,
-					TYPEID_VUZENEWS, TYPEID_HEADER, null),
-		};
-
-	}
 }
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesEntry.java b/com/aelitis/azureus/activities/VuzeActivitiesEntry.java
index da2a0e5..de76226 100644
--- a/com/aelitis/azureus/activities/VuzeActivitiesEntry.java
+++ b/com/aelitis/azureus/activities/VuzeActivitiesEntry.java
@@ -23,7 +23,6 @@ import java.util.Map;
 
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.global.GlobalManager;
-import org.gudy.azureus2.core3.global.GlobalManagerAdapter;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.torrent.TOTorrentException;
 import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
@@ -551,8 +550,6 @@ public class VuzeActivitiesEntry
 			if (torrent != null) {
 				sc.setDisplayName(TorrentUtils.getLocalisedName(torrent));
 				sc.setHash(torrent.getHashWrapper().toBase32String(), ourContent);
-			} else {
-				throw new Exception("No Display Name");
 			}
 		}
 		
@@ -561,8 +558,6 @@ public class VuzeActivitiesEntry
 			if ( assetHash != null ){
 
 				sc.setHash(assetHash, true);
-			} else {
-				throw new Exception("No Download Info");
 			}
 		}
 
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesEntryBuddy.java b/com/aelitis/azureus/activities/VuzeActivitiesEntryBuddy.java
deleted file mode 100644
index 5e9d520..0000000
--- a/com/aelitis/azureus/activities/VuzeActivitiesEntryBuddy.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * Created on Jun 17, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
- 
-package com.aelitis.azureus.activities;
-
-import java.util.Map;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.VuzeBuddyListener;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author TuxPaper
- * @created Jun 17, 2008
- *
- */
-public class VuzeActivitiesEntryBuddy
-	extends VuzeActivitiesEntry
-	implements VuzeBuddyListener
-{
-	protected VuzeBuddy buddy;
-	private String buddyID;
-
-
-	public void loadCommonFromMap(Map map) {
-		super.loadCommonFromMap(map);
-
-		Map mapNewBuddy = (Map) MapUtils.getMapObject(map, "buddy", null,
-				Map.class);
-		if (mapNewBuddy == null) {
-			String buddyID = MapUtils.getMapString(map, "buddyID", null);
-			if (buddyID != null) {
-				buddy = VuzeBuddyManager.getBuddyByLoginID(buddyID);
-			}
-		} else {
-			buddy = VuzeBuddyManager.getOrCreatePotentialBuddy(mapNewBuddy);
-		}
-		
-		if (buddy != null) {
-			buddy.addListener(this);
-		}
-	}
-
-	// @see com.aelitis.azureus.activities.VuzeActivitiesEntry#toMap()
-	public Map toMap() {
-		Map map = super.toMap();
-
-		if (buddy != null) {
-			map.put("buddy", buddy.toMap());
-			map.put("buddyID", buddy.getLoginID());
-		} else if (buddyID != null) {
-			map.put("buddyID", buddyID);
-		}
-		return map;
-	}
-
-	public VuzeBuddy getBuddy() {
-		if (buddy == null && buddyID != null) {
-			buddy = VuzeBuddyManager.getBuddyByLoginID(buddyID);
-		}
-		return buddy;
-	}
-
-	public void setBuddy(VuzeBuddy buddy) {
-		if (buddy != this.buddy) {
-			if (this.buddy != null) {
-				buddy.removeListener(this);
-			}
-		}
-		this.buddy = buddy;
-
-		if (buddy != null) {
-			buddy.addListener(this);
-		}
-	}
-	
-	public void setBuddyID(String buddyID) {
-		this.buddyID = buddyID;
-		buddy = null;
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddyListener#buddyAdded(com.aelitis.azureus.buddy.VuzeBuddy, int)
-	public void buddyAdded(VuzeBuddy buddy, int position) {
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddyListener#buddyChanged(com.aelitis.azureus.buddy.VuzeBuddy)
-	public void buddyChanged(VuzeBuddy buddy) {
-		VuzeActivitiesManager.triggerEntryChanged(this);
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddyListener#buddyOrderChanged()
-	public void buddyOrderChanged() {
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddyListener#buddyRemoved(com.aelitis.azureus.buddy.VuzeBuddy)
-	public void buddyRemoved(VuzeBuddy buddy) {
-	}
-}
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesEntryBuddyLinkup.java b/com/aelitis/azureus/activities/VuzeActivitiesEntryBuddyLinkup.java
deleted file mode 100644
index dd167d7..0000000
--- a/com/aelitis/azureus/activities/VuzeActivitiesEntryBuddyLinkup.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Created on Apr 15, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.activities;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.SystemTime;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author TuxPaper
- * @created Apr 15, 2008
- *
- */
-public class VuzeActivitiesEntryBuddyLinkup
-	extends VuzeActivitiesEntryBuddy
-{
-	public VuzeActivitiesEntryBuddyLinkup() {
-		super();
-	}
-
-	public VuzeActivitiesEntryBuddyLinkup(VuzeBuddy buddy) {
-		setBuddy(buddy);
-
-		String text = MessageText.getString("v3.activity.buddy-linkup",
-				new String[] {
-					buddy.getProfileAHREF("new-buddy-inform")
-				});
-		
-		setTypeID("buddy-new", true);
-		// show multiple link ups
-		setID("buddy-new-" + buddy.getLoginID() + "-" + SystemTime.getCurrentTime());
-		setText(text);
-	}
-}
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesEntryBuddyRequest.java b/com/aelitis/azureus/activities/VuzeActivitiesEntryBuddyRequest.java
deleted file mode 100644
index f8a9cc6..0000000
--- a/com/aelitis/azureus/activities/VuzeActivitiesEntryBuddyRequest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * Created on Apr 15, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.activities;
-
-import java.util.Map;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.util.ConstantsV3;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author TuxPaper
- * @created Apr 15, 2008
- *
- */
-public class VuzeActivitiesEntryBuddyRequest
-	extends VuzeActivitiesEntryBuddy
-{
-	private String urlAccept;
-
-	public String getUrlAccept() {
-		return urlAccept;
-	}
-
-	public VuzeActivitiesEntryBuddyRequest() {
-		super();
-	}
-
-	public void init(VuzeBuddy buddy, String acceptURL, long attempNumber) {
-		this.buddy = buddy;
-
-		urlAccept = getContentNetwork().appendURLSuffix(acceptURL, false, true);
-
-		String textID = "v3.activity.buddy-request";
-		if (attempNumber > 1) {
-			textID += ".multi";
-		}
-		String text = MessageText.getString(textID, new String[] {
-			buddy.getProfileAHREF(VuzeActivitiesConstants.TYPEID_BUDDYREQUEST),
-			urlAccept,
-			"" + attempNumber
-		});
-		
-		setText(text);
-		setTypeID(VuzeActivitiesConstants.TYPEID_BUDDYREQUEST, true);
-		setID(buildID(buddy.getCode()));
-	}
-	
-	// @see com.aelitis.azureus.activities.VuzeActivitiesEntryBuddy#loadCommonFromMap(java.util.Map)
-	public void loadCommonFromMap(Map map) {
-		super.loadCommonFromMap(map);
-
-		urlAccept = MapUtils.getMapString(map, "url-accept", urlAccept);
-		if (urlAccept != null) {
-			urlAccept = getContentNetwork().appendURLSuffix(urlAccept, false, true);
-		}
-	}
-	
-	// @see com.aelitis.azureus.activities.VuzeActivitiesEntryBuddy#toMap()
-	public Map toMap() {
-		Map map = super.toMap();
-		
-		map.put("url-accept", urlAccept);
-		
-		return map;
-	}
-
-	public static String buildID(String code) {
-		return VuzeActivitiesConstants.TYPEID_BUDDYREQUEST + "-" + code;
-	}
-
-}
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesEntryContentShare.java b/com/aelitis/azureus/activities/VuzeActivitiesEntryContentShare.java
deleted file mode 100644
index 51ac6b1..0000000
--- a/com/aelitis/azureus/activities/VuzeActivitiesEntryContentShare.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/**
- * Created on Apr 15, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.activities;
-
-import java.util.Map;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.torrent.TOTorrentException;
-import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
-import org.gudy.azureus2.core3.util.SystemTime;
-import org.gudy.azureus2.core3.util.UrlUtils;
-
-import com.aelitis.azureus.buddy.VuzeShareable;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentV3;
-import com.aelitis.azureus.util.*;
-import com.aelitis.azureus.util.LoginInfoManager.LoginInfo;
-
-/**
- * @author TuxPaper
- * @created Apr 15, 2008
- *
- */
-public class VuzeActivitiesEntryContentShare
-	extends VuzeActivitiesEntryBuddy
-{
-	public static final String URL_USERMESSAGE = "showsharemessage";	
-	
-	private String userMessage;
-	public String getUserMessage() {
-		return userMessage;
-	}
-
-	public void setUserMessage(String userMessage) {
-		this.userMessage = userMessage;
-	}
-
-	private long version;
-
-	public VuzeActivitiesEntryContentShare() {
-		super();
-	}
-
-	public VuzeActivitiesEntryContentShare(VuzeShareable content,
-			String message) throws NotLoggedInException {
-		if (content == null) {
-			return;
-		}
-		if (!LoginInfoManager.getInstance().isLoggedIn()) {
-			VuzeBuddyManager.log("Can't share download: Not logged in");
-			throw new NotLoggedInException();
-		}
-
-		DownloadManager dm = content.getDownloadManager();
-		
-		TOTorrent torrent = content.getTorrent();
-
-		boolean ourContent = content.isPlatformContent();
-
-		setPlayable(content.canPlay());
-
-		LoginInfo userInfo = LoginInfoManager.getInstance().getUserInfo();
-
-		setTypeID(VuzeActivitiesConstants.TYPEID_BUDDYSHARE, true);
-		setID(VuzeActivitiesConstants.TYPEID_BUDDYSHARE + "-"
-				+ SystemTime.getCurrentTime());
-		setTorrent(torrent);
-
-		{
-			// For older clients, we must build the text for them
-
-  		String contentString;
-  
-  		String displayName = content.getDisplayName();
-  		if (ourContent || torrent == null) {
-				ContentNetwork cn = DataSourceUtils.getContentNetwork(content);
-				if (cn == null) {
-					contentString = displayName;
-				} else {
-					String url = cn.getContentDetailsService(content.getHash(),
-							VuzeActivitiesConstants.TYPEID_BUDDYSHARE);
-
-					contentString = "<A HREF=\"" + url + "\">" + displayName + "</A>";
-				}
-			} else {
-  			contentString = displayName;
-  		}
-  
-  		String textid = (message == null || message.length() == 0)
-  				? "v3.activity.share-content.no-msg" : "v3.activity.share-content";
-  
-  		String text = MessageText.getString(textid, new String[] {
-  			userInfo.getProfileAHREF(VuzeActivitiesConstants.TYPEID_BUDDYSHARE),
-  			contentString,
-  			userInfo.displayName,
-  			UrlUtils.encode(message)
-  		});
-  
-  		setText(text);
-		}
-		
-		if (dm != null) {
-			setTorrentName(PlatformTorrentUtils.getContentTitle2(dm));
-		} else {
-			setTorrentName(content.getDisplayName());
-		}
-
-		setAssetImageURL(content.getThumbURL());
-	  
-		userMessage = message;
-
-		version = 2;
-
-		setAssetHash(content.getHash());
-		if ( dm != null) {
-			setDownloadManager( dm );
-		}
-		setShowThumb(true);
-		if (content.getImageBytes() == null) {
-			setImageBytes(PlatformTorrentUtils.getContentThumbnail(torrent));
-		} else {
-			setImageBytes(content.getImageBytes());
-		}
-		setIsPlatformContent(ourContent);
-		// The recipient will set the timestamp
-		setTimestamp(0);
-	}
-	
-	// @see com.aelitis.azureus.activities.VuzeActivitiesEntryBuddy#toMap()
-	public Map toMap() {
-		// ensure we write the torrent to the map
-		setDownloadManager(null);
-		
-		Map map = super.toMap();
-		
-		map.put("version", new Long(version));
-		map.put("userMessage", userMessage);
-		
-		return map;
-	}
-
-	// @see com.aelitis.azureus.activities.VuzeActivitiesEntry#loadCommonFromMap(java.util.Map)
-	public void loadCommonFromMap(Map map) {
-		super.loadCommonFromMap(map);
-
-		Map torrentMap = MapUtils.getMapMap(map, "torrent", null);
-		if (torrentMap != null) {
-			try {
-				setTorrent(TOTorrentFactory.deserialiseFromMap(torrentMap));
-			} catch (TOTorrentException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-		
-		version = MapUtils.getMapLong(map, "version", 1);
-		
-		if (version >= 2 && buddy != null) {
-			userMessage = MapUtils.getMapString(map, "userMessage", null);
-			String textid = (userMessage == null || userMessage.length() == 0)
-					? "v3.activity.share-content.no-msg" : "v3.activity.share-content";
-
-  		String contentString;
-  	  
-  		if (isPlatformContent() || getTorrent() == null) {
-  			String url = getContentNetwork().getContentDetailsService(
-						getAssetHash(), VuzeActivitiesConstants.TYPEID_BUDDYSHARE);
- 
-  			contentString = "<A HREF=\"" + url + "\">" + getTorrentName()
-  					+ "</A>";
-  		} else {
-  			contentString = getTorrentName();
-  		}
-			
-			setText(MessageText.getString(textid, new String[] {
-				buddy.getProfileAHREF(VuzeActivitiesConstants.TYPEID_BUDDYSHARE),
-				contentString,
-				buddy.getDisplayName(),
-				URL_USERMESSAGE,
-  			UrlUtils.encode(userMessage)
-			}));
-		}
-
-		setDRM(MapUtils.getMapBoolean(torrentMap, "isDRM", false));
-	}
-}
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesManager.java b/com/aelitis/azureus/activities/VuzeActivitiesManager.java
index 7fe2268..1a0f2ec 100644
--- a/com/aelitis/azureus/activities/VuzeActivitiesManager.java
+++ b/com/aelitis/azureus/activities/VuzeActivitiesManager.java
@@ -20,22 +20,13 @@ package com.aelitis.azureus.activities;
 
 import java.util.*;
 
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.download.DownloadManagerState;
-import org.gudy.azureus2.core3.global.GlobalManager;
-import org.gudy.azureus2.core3.global.GlobalManagerListener;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreLifecycleAdapter;
 import com.aelitis.azureus.core.cnetwork.*;
-import com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger;
 import com.aelitis.azureus.core.messenger.config.PlatformVuzeActivitiesMessenger;
-import com.aelitis.azureus.core.messenger.config.RatingUpdateListener2;
-import com.aelitis.azureus.core.torrent.*;
 import com.aelitis.azureus.util.ConstantsVuze;
-import com.aelitis.azureus.util.DataSourceUtils;
 import com.aelitis.azureus.util.MapUtils;
 
 /**
@@ -51,26 +42,22 @@ public class VuzeActivitiesManager
 
 	private static final long DEFAULT_PLATFORM_REFRESH = 60 * 60 * 1000L * 24;
 
-	private static final long RATING_REMINDER_DELAY = 1000L * 60 * 60 * 24 * 3;
-
-	private static final long WEEK_MS = 604800000L;
-
 	private static final String SAVE_FILENAME = "VuzeActivities.config";
 
-	private static ArrayList listeners = new ArrayList();
+	private static ArrayList<VuzeActivitiesListener> listeners = new ArrayList<VuzeActivitiesListener>();
 
-	private static ArrayList allEntries = new ArrayList();
+	private static ArrayList<VuzeActivitiesEntry> allEntries = new ArrayList<VuzeActivitiesEntry>();
 
 	private static AEMonitor allEntries_mon = new AEMonitor("VuzeActivityMan");
 
-	private static List removedEntries = new ArrayList();
+	private static List<VuzeActivitiesEntry> removedEntries = new ArrayList<VuzeActivitiesEntry>();
 
 	private static PlatformVuzeActivitiesMessenger.GetEntriesReplyListener replyListener;
 
 	private static AEDiagnosticsLogger diag_logger;
 
 	/** Key: NetworkID, Value: last time we pulled news **/ 
-	private static Map<String, Long> lastNewsAt = new HashMap();
+	private static Map<String, Long> lastNewsAt = new HashMap<String, Long>();
 
 	private static boolean skipAutoSave = true;
 
@@ -158,89 +145,6 @@ public class VuzeActivitiesManager
 		};
 
 		pullActivitiesNow(5000);
-
-		PlatformRatingMessenger.addListener(new RatingUpdateListener2() {
-			// @see com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger.RatingUpdateListener#ratingUpdated(com.aelitis.azureus.core.torrent.RatingInfoList)
-			public void ratingUpdated(RatingInfoList rating) {
-				if (!(rating instanceof SingleUserRatingInfo)) {
-					return;
-				}
-				Object[] allEntriesArray = allEntries.toArray();
-				for (int i = 0; i < allEntriesArray.length; i++) {
-					VuzeActivitiesEntry entry = (VuzeActivitiesEntry) allEntriesArray[i];
-					if (entry == null) {
-						continue;
-					}
-					String typeID = entry.getTypeID();
-					DownloadManager dm = entry.getDownloadManger();
-					if (VuzeActivitiesConstants.TYPEID_RATING_REMINDER.equals(typeID)
-							&& dm != null) {
-						try {
-							String hash = dm.getTorrent().getHashWrapper().toBase32String();
-							if (rating.hasHash(hash)
-									&& rating.getRatingValue(hash,
-											PlatformRatingMessenger.RATE_TYPE_CONTENT) != GlobalRatingUtils.RATING_NONE) {
-								removeEntries(new VuzeActivitiesEntry[] {
-									entry
-								});
-							}
-						} catch (Exception e) {
-						}
-					}
-				}
-			}
-		});
-
-		GlobalManagerListener gmListener = new GlobalManagerListener() {
-
-			public void seedingStatusChanged(boolean seeding_only_mode, boolean b) {
-			}
-
-			public void downloadManagerRemoved(DownloadManager dm) {
-			}
-
-			public void downloadManagerAdded(DownloadManager dm) {
-				List entries = registerDM(dm);
-				if (entries != null && entries.size() > 0) {
-					addEntries((VuzeActivitiesEntry[]) entries.toArray(new VuzeActivitiesEntry[0]));
-				}
-			}
-
-			public void destroyed() {
-			}
-
-			public void destroyInitiated() {
-			}
-		};
-
-		
-		
-		
-		List newEntries = new ArrayList();
-		GlobalManager gm = core.getGlobalManager();
-		gm.addListener(gmListener, false);
-
-		List downloadManagers = gm.getDownloadManagers();
-		for (Iterator iter = downloadManagers.iterator(); iter.hasNext();) {
-			DownloadManager dm = (DownloadManager) iter.next();
-			List entries = registerDM(dm);
-			if (entries != null && entries.size() > 0) {
-				newEntries.addAll(entries);
-			}
-		}
-
-		if (newEntries.size() > 0) {
-			trimReminders(newEntries, false);
-			addEntries((VuzeActivitiesEntry[]) newEntries.toArray(new VuzeActivitiesEntry[0]));
-		}
-
-		try {
-			allEntries_mon.enter();
-
-			trimReminders(allEntries, true);
-		} finally {
-			allEntries_mon.exit();
-		}
 	}
 
 	/**
@@ -266,102 +170,6 @@ public class VuzeActivitiesManager
 	}
 
 	/**
-	 * @param allEntries2
-	 *
-	 * @since 3.0.4.3
-	 */
-	private static void trimReminders(List entries, boolean liveRemove) {
-		List listReminders = new ArrayList();
-		for (Iterator iter = entries.iterator(); iter.hasNext();) {
-			VuzeActivitiesEntry entry = (VuzeActivitiesEntry) iter.next();
-			if (VuzeActivitiesConstants.TYPEID_RATING_REMINDER.equals(entry.getTypeID())) {
-				listReminders.add(entry);
-			}
-		}
-		if (listReminders.size() > 3) {
-			Collections.sort(listReminders); // will be sorted by date ascending
-			long weekBreak = SystemTime.getCurrentTime() - (WEEK_MS * 4);
-			int numInWeek = 0;
-			for (Iterator iter = listReminders.iterator(); iter.hasNext();) {
-				VuzeActivitiesEntry entry = (VuzeActivitiesEntry) iter.next();
-
-				if (entry.getTimestamp() < weekBreak) {
-					numInWeek++;
-					if (numInWeek > 3) {
-						if (liveRemove) {
-							removeEntries(new VuzeActivitiesEntry[] {
-								entry
-							});
-						} else {
-							entries.remove(entry);
-						}
-					}
-				} else {
-					numInWeek = 1;
-					while (entry.getTimestamp() >= weekBreak) {
-						weekBreak += WEEK_MS;
-					}
-				}
-			}
-		}
-	}
-
-
-	private static List registerDM(DownloadManager dm) {
-		TOTorrent torrent = dm.getTorrent();
-		if (PlatformTorrentUtils.getAdId(torrent) != null) {
-			return null;
-		}
-
-		boolean isContent = PlatformTorrentUtils.isContent(torrent, true);
-
-		List entries = new ArrayList();
-
-		try {
-			if (isContent) {
-				long networkID = PlatformTorrentUtils.getContentNetworkID(torrent);
-				long completedOn = dm.getDownloadState().getLongParameter(
-						DownloadManagerState.PARAM_DOWNLOAD_COMPLETED_TIME);
-				if (completedOn > 0
-						&& networkID == ConstantsVuze.getDefaultContentNetwork().getID()
-						&& SystemTime.getCurrentTime() - completedOn > RATING_REMINDER_DELAY) {
-					int userRating = PlatformTorrentUtils.getUserRating(torrent);
-					if (userRating < 0) {
-						VuzeActivitiesEntry entry = new VuzeActivitiesEntry();
-						entries.add(entry);
-
-						String hash = torrent.getHashWrapper().toBase32String();
-						String title;
-						ContentNetwork cn = DataSourceUtils.getContentNetwork(dm);
-						if (cn == null) {
-							title = PlatformTorrentUtils.getContentTitle2(dm);
-						} else {
-							String url = cn.getContentDetailsService(hash, "activity-"
-									+ VuzeActivitiesConstants.TYPEID_RATING_REMINDER);
-
-							title = "<A HREF=\"" + url + "\">"
-									+ PlatformTorrentUtils.getContentTitle2(dm) + "</A>";
-						}
-						entry.setAssetHash(hash);
-
-						entry.setDownloadManager(dm);
-						entry.setShowThumb(true);
-						entry.setID(hash + ";r" + completedOn);
-						entry.setText("To improve your recommendations, please rate "
-								+ title);
-						entry.setTimestamp(SystemTime.getCurrentTime());
-						entry.setTypeID(VuzeActivitiesConstants.TYPEID_RATING_REMINDER, true);
-					}
-				}
-			}
-		} catch (Throwable t) {
-			// ignore
-		}
-
-		return entries;
-	}
-
-	/**
 	 * Pull entries from webapp
 	 * 
 	 * @param agoMS Pull all events within this timespan (ms)
@@ -370,6 +178,7 @@ public class VuzeActivitiesManager
 	 * @since 3.0.4.3
 	 */
 	public static void pullActivitiesNow(long delay) {
+		/*
 		ContentNetworkManager cnm = ContentNetworkManagerFactory.getSingleton();
 		if (cnm == null) {
 			return;
@@ -377,15 +186,19 @@ public class VuzeActivitiesManager
 		
 		ContentNetwork[] contentNetworks = cnm.getContentNetworks();
 		for (ContentNetwork cn : contentNetworks) {
+		*/
+		{
+			// short circuit.. only get vuzenews from default network
+			ContentNetwork cn = ConstantsVuze.getDefaultContentNetwork();
 			if (cn == null) {
-				continue;
+				return; //continue;
 			}
 			
 			Object oIsActive = cn.getPersistentProperty(ContentNetwork.PP_ACTIVE);
 			boolean isActive = (oIsActive instanceof Boolean)
 					? ((Boolean) oIsActive).booleanValue() : false;
 			if (!isActive) {
-				continue;
+				return; //continue;
 			}
 			
 			String id = "" + cn.getID();
@@ -393,6 +206,9 @@ public class VuzeActivitiesManager
 			long lastPullTime = oLastPullTime != null ? oLastPullTime.longValue() : 0;
 			long now = SystemTime.getCurrentTime();
 			long diff = now - lastPullTime;
+			if (diff < 5000) {
+				return;
+			}
 			if (diff > MAX_LIFE_MS) {
 				diff = MAX_LIFE_MS;
 			}
@@ -403,7 +219,7 @@ public class VuzeActivitiesManager
 	}
 	
 	public static void clearLastPullTimes() {
-		lastNewsAt = new HashMap();
+		lastNewsAt = new HashMap<String, Long>();
 	}
 
 	/**
@@ -436,8 +252,17 @@ public class VuzeActivitiesManager
 		skipAutoSave = true;
 
 		try {
-			Map map = FileUtil.readResilientConfigFile(SAVE_FILENAME);
-
+			Map<?,?> map = FileUtil.readResilientConfigFile(SAVE_FILENAME);
+
+			// Clear all entries if we aren't on v2
+			if (map != null && map.size() > 0
+					&& MapUtils.getMapLong(map, "version", 0) < 2) {
+				clearLastPullTimes();
+				skipAutoSave = false;
+				saveEventsNow();
+				return;
+			}
+			
 			long cutoffTime = getCutoffTime();
 
 			try {
@@ -457,7 +282,7 @@ public class VuzeActivitiesManager
   						lastVuzeNewsAt));
   			}
 			}
-
+			
 			Object value;
 
 			List newRemovedEntries = (List) MapUtils.getMapObject(map,
@@ -492,10 +317,6 @@ public class VuzeActivitiesManager
 				VuzeActivitiesEntry entry = createEntryFromMap((Map) value, true);
 
 				if (entry != null) {
-					if (VuzeActivitiesConstants.TYPEID_RATING_REMINDER.equals(entry.getTypeID())) {
-						entry.setShowThumb(true);
-					}
-
 					if (entry.getTimestamp() > cutoffTime) {
 						entriesToAdd.add(entry);
 					}
@@ -521,6 +342,7 @@ public class VuzeActivitiesManager
 
 			Map mapSave = new HashMap();
 			mapSave.put("LastChecks", lastNewsAt);
+			mapSave.put("version", new Long(2));
 
 			List entriesList = new ArrayList();
 
@@ -539,8 +361,8 @@ public class VuzeActivitiesManager
 			mapSave.put("entries", entriesList);
 
 			List removedEntriesList = new ArrayList();
-			for (Iterator iter = removedEntries.iterator(); iter.hasNext();) {
-				VuzeActivitiesEntry entry = (VuzeActivitiesEntry) iter.next();
+			for (Iterator<VuzeActivitiesEntry> iter = removedEntries.iterator(); iter.hasNext();) {
+				VuzeActivitiesEntry entry = iter.next();
 				removedEntriesList.add(entry.toDeletedMap());
 			}
 			mapSave.put("removed-entries", removedEntriesList);
@@ -616,8 +438,8 @@ public class VuzeActivitiesManager
 				saveEvents();
 			}
 
-  		for (Iterator iter = existingEntries.iterator(); iter.hasNext();) {
-  			VuzeActivitiesEntry entry = (VuzeActivitiesEntry) iter.next();
+  		for (Iterator<VuzeActivitiesEntry> iter = existingEntries.iterator(); iter.hasNext();) {
+  			VuzeActivitiesEntry entry = iter.next();
   			triggerEntryChanged(entry);
   		}
 		}
@@ -662,8 +484,8 @@ public class VuzeActivitiesManager
 		try {
 			allEntries_mon.enter();
 
-			for (Iterator iter = allEntries.iterator(); iter.hasNext();) {
-				VuzeActivitiesEntry entry = (VuzeActivitiesEntry) iter.next();
+			for (Iterator<VuzeActivitiesEntry> iter = allEntries.iterator(); iter.hasNext();) {
+				VuzeActivitiesEntry entry = iter.next();
 				if (entry == null) {
 					continue;
 				}
@@ -680,7 +502,7 @@ public class VuzeActivitiesManager
 	}
 
 	public static VuzeActivitiesEntry[] getAllEntries() {
-		return (VuzeActivitiesEntry[]) allEntries.toArray(new VuzeActivitiesEntry[allEntries.size()]);
+		return allEntries.toArray(new VuzeActivitiesEntry[allEntries.size()]);
 	}
 	
 	public static int getNumEntries() {
@@ -724,15 +546,7 @@ public class VuzeActivitiesManager
 		VuzeActivitiesEntry entry;
 		String typeID = MapUtils.getMapString(map, "typeID", MapUtils.getMapString(
 				map, "type-id", null));
-		if (VuzeActivitiesConstants.TYPEID_BUDDYREQUEST.equals(typeID)) {
-			entry = new VuzeActivitiesEntryBuddyRequest();
-		} else if (VuzeActivitiesConstants.TYPEID_BUDDYSHARE.equals(typeID)) {
-			entry = new VuzeActivitiesEntryContentShare();
-		} else if (VuzeActivitiesConstants.TYPEID_BUDDYLINKUP.equals(typeID)) {
-			entry = new VuzeActivitiesEntryBuddyLinkup();
-		} else {
-			entry = new VuzeActivitiesEntry();
-		}
+		entry = new VuzeActivitiesEntry();
 		entry.setContentNetworkID(defaultContentNetworkID);
 		if (internalMap) {
 			entry.loadFromInternalMap(map);
diff --git a/com/aelitis/azureus/buddy/QueuedVuzeShare.java b/com/aelitis/azureus/buddy/QueuedVuzeShare.java
deleted file mode 100644
index 0a6051c..0000000
--- a/com/aelitis/azureus/buddy/QueuedVuzeShare.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * Created on Apr 22, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.buddy;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.gudy.azureus2.core3.util.SystemTime;
-
-import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.activities.VuzeActivitiesManager;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author TuxPaper
- * @created Apr 22, 2008
- *
- */
-public class QueuedVuzeShare
-{
-	private String code;
-
-	private String pk;
-
-	private String downloadHash;
-
-	private VuzeActivitiesEntry entry;
-	
-	private long sharedOn;
-
-	/**
-	 * @param map
-	 */
-	public QueuedVuzeShare(Map map) {
-		loadFromMap(map);
-	}
-
-	/**
-	 * 
-	 */
-	public QueuedVuzeShare() {
-		setSharedOn(SystemTime.getCurrentTime());
-	}
-
-	/**
-	 * @param code the code to set
-	 */
-	public void setCode(String code) {
-		this.code = code;
-	}
-
-	/**
-	 * @return the code
-	 */
-	public String getCode() {
-		return code;
-	}
-
-	/**
-	 * @param pk the pk to set
-	 */
-	public void setPk(String pk) {
-		this.pk = pk;
-	}
-
-	/**
-	 * @return the pk
-	 */
-	public String getPk() {
-		return pk;
-	}
-
-	/**
-	 * @param downloadHash the downloadHash to set
-	 */
-	public void setDownloadHash(String downloadHash) {
-		this.downloadHash = downloadHash;
-	}
-
-	/**
-	 * @return the downloadHash
-	 */
-	public String getDownloadHash() {
-		return downloadHash;
-	}
-
-	/**
-	 * @param entry the entry to set
-	 */
-	public void setActivityEntry(VuzeActivitiesEntry entry) {
-		this.entry = entry;
-	}
-
-	/**
-	 * @return the entry
-	 */
-	public VuzeActivitiesEntry getActivityEntry() {
-		return entry;
-	}
-
-	/**
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	public Map toMap() {
-		Map map = new HashMap();
-		map.put("code", code);
-		if (entry != null) {
-			map.put("ActivityEntry", entry.toMap());
-		}
-		map.put("hash", downloadHash);
-		map.put("pk", pk);
-		map.put("sharedOn", new Long(sharedOn));
-
-		return map;
-	}
-
-	/**
-	 * @param map
-	 *
-	 * @since 3.0.5.3
-	 */
-	private void loadFromMap(Map map) {
-		setCode(MapUtils.getMapString(map, "code", null));
-		setSharedOn(MapUtils.getMapLong(map, "sharedOn", 0));
-		
-		Map entryMap = MapUtils.getMapMap(map, "ActivityEntry", null);
-		if (entryMap != null) {
-			VuzeActivitiesEntry entry = VuzeActivitiesManager.createEntryFromMap(
-					entryMap, true);
-			setActivityEntry(entry);
-			if (sharedOn == 0) {
-				setSharedOn(entry.getTimestamp());
-			}
-		} else {
-			setActivityEntry(null);
-		}
-		setDownloadHash(MapUtils.getMapString(map, "hash", null));
-		setPk(MapUtils.getMapString(map, "pk", null));
-		if (sharedOn == 0) {
-			sharedOn = SystemTime.getCurrentTime();
-		}
-	}
-
-	public long getSharedOn() {
-		return sharedOn;
-	}
-
-	public void setSharedOn(long sharedOn) {
-		this.sharedOn = sharedOn;
-	}
-}
diff --git a/com/aelitis/azureus/buddy/VuzeBuddy.java b/com/aelitis/azureus/buddy/VuzeBuddy.java
deleted file mode 100644
index 6596843..0000000
--- a/com/aelitis/azureus/buddy/VuzeBuddy.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/**
- * Created on Apr 14, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.buddy;
-
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.buddy.chat.ChatMessage;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPlugin;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentV3;
-
-/**
- * @author TuxPaper
- * @created Apr 14, 2008
- *
- */
-public interface VuzeBuddy
-	extends Comparator, Comparable
-{
-		/**
-		 * These constants are ordered so, for example, to test if chat supported do a
-		 *     getVersion() >= VERSION_CHAT
-		 */
-	
-	public static final int	VERSION_INITIAL	= BuddyPlugin.VERSION_INITIAL;
-	public static final int	VERSION_CHAT	= BuddyPlugin.VERSION_CHAT;
-		
-	public String getDisplayName();
-
-	public void setDisplayName(String displayName);
-
-	public String getLoginID();
-
-	public void setLoginID(String loginName);
-
-	public long getLastUpdated();
-
-	public void setLastUpdated(long lastUpdated);
-
-	public byte[] getAvatar();
-
-	public void setAvatar(byte[] image);
-
-	public boolean isOnline( boolean is_connected );
-
-		// returns a VERSION constant from above list. This is the maximum version of
-		// any of the buddies identities
-	
-	public int getVersion();
-	
-	public String[] getPublicKeys();
-	
-	public void addPublicKey(String pk);
-	
-	public void removePublicKey(String pk);
-	
-	public void sendActivity(VuzeActivitiesEntry entry) throws NotLoggedInException;
-
-	public void loadFromMap(Map mapNewBuddy);
-
-	public void shareDownload(VuzeShareable content, String message) throws NotLoggedInException;
-
-	public void sendPayloadMap(Map map) throws NotLoggedInException;
-
-	public void sendBuddyMessage(String namespace, Map map) throws NotLoggedInException;
-	
-	public Map toMap();
-
-	public String getCode();
-
-	public void setCode(String code);
-
-	public Set<String>
-	getSubscribableCategories();
-	
-	public boolean
-	canSubscribeToCategory();
-	
-	public boolean
-	isSubscribedToCategory(
-		String		category );
-	
-	public void
-	setSubscribedToCategory(
-		String		category,
-		boolean		subscribed );
-
-	public Set<String>
-	getPublishedCategories();
-
-	public boolean
-	isPublishedCategory(
-		String		category );
-	
-	public boolean
-	canSetPublishedCategory(
-		String		category );
-	
-	public void
-	setPublishedCategory(
-		String		category,
-		boolean		published );
-	
-	String getProfileUrl(String referer);
-
-	/**
-	 * @param createdOn
-	 *
-	 * @since 3.0.5.3
-	 */
-	void setCreatedOn(long createdOn);
-
-	/**
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	long getCreatedOn();
-
-	/**
-	 * @throws NotLoggedInException
-	 *
-	 * @since 3.0.5.3
-	 */
-	void tellBuddyToSyncUp()
-			throws NotLoggedInException;
-
-	/**
-	 * @param referer
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	String getProfileAHREF(String referer);
-
-	/**
-	 * 
-	 *
-	 * @since 3.0.5.3
-	 */
-	String toDebugString();
-
-	/**
-	 * @param referer
-	 * @param useImage
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	String getProfileAHREF(String referer, boolean useImage);
-
-	/**
-	 * @param l
-	 *
-	 * @since 3.1.0.1
-	 */
-	void addListener(VuzeBuddyListener l);
-
-	/**
-	 * @param l
-	 *
-	 * @since 3.1.0.1
-	 */
-	void removeListener(VuzeBuddyListener l);
-
-	/**
-	 * @return
-	 *
-	 * @since 3.1.0.1
-	 */
-	VuzeBuddyListener[] getListeners();
-	
-	public int
-	getStoredChatMessageCount();
-
-	public List
-	getStoredChatMessages();
-	
-	public void
-	storeChatMessage(
-		ChatMessage		msg );
-	
-	public void
-	deleteChatMessage(
-		ChatMessage		msg );
-}
diff --git a/com/aelitis/azureus/buddy/VuzeBuddyCreator.java b/com/aelitis/azureus/buddy/VuzeBuddyCreator.java
deleted file mode 100644
index 6e3317e..0000000
--- a/com/aelitis/azureus/buddy/VuzeBuddyCreator.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Created on Apr 14, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
- 
-package com.aelitis.azureus.buddy;
-
-import java.util.Map;
-
-/**
- * @author TuxPaper
- * @created Apr 14, 2008
- *
- */
-public interface VuzeBuddyCreator
-{
-	/**
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	public VuzeBuddy createBuddy(String publicKey);
-
-	/**
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	public VuzeBuddy createBuddy();
-	
-	/**
-	 * 
-	 * @param mapBuddy 
-	 * @return
-	 *
-	 * @since 3.1.0.1
-	 */
-	public VuzeBuddy createPotentialBuddy(Map mapBuddy);
-}
diff --git a/com/aelitis/azureus/buddy/VuzeBuddyListener.java b/com/aelitis/azureus/buddy/VuzeBuddyListener.java
deleted file mode 100644
index b5e513d..0000000
--- a/com/aelitis/azureus/buddy/VuzeBuddyListener.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Created on Apr 23, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
- 
-package com.aelitis.azureus.buddy;
-
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-
-/**
- * @author TuxPaper
- * @created Apr 23, 2008
- *
- */
-public interface VuzeBuddyListener
-{
-	/**
-	 * A buddy has been removed from the {@link VuzeBuddyManager}
-	 * @param buddy
-	 *
-	 * @since 3.0.5.3
-	 */
-	public void buddyRemoved(VuzeBuddy buddy);
-
-	/**
-	 * A buddy has been added to {@link VuzeBuddyManager}
-	 * 
-	 * @param buddy
-	 *
-	 * @since 3.0.5.3
-	 */
-	public void buddyAdded(VuzeBuddy buddy, int position);
-
-	/**
-	 * A buddy's information has changed (not including position)
-	 * 
-	 * @param buddy
-	 *
-	 * @since 3.0.5.3
-	 */
-	public void buddyChanged(VuzeBuddy buddy);
-
-	/**
-	 * The order of the Buddy List has changed 
-	 *
-	 * @since 3.0.5.3
-	 */
-	public void buddyOrderChanged();
-}
diff --git a/com/aelitis/azureus/buddy/VuzeShareable.java b/com/aelitis/azureus/buddy/VuzeShareable.java
deleted file mode 100644
index b827291..0000000
--- a/com/aelitis/azureus/buddy/VuzeShareable.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Created on Apr 8, 2009
- * Created by Paul Gardner
- * 
- * Copyright 2009 Vuze, Inc.  All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-
-package com.aelitis.azureus.buddy;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-
-import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfo;
-
-public interface 
-VuzeShareable 
-{
-	public String
-	getHash();
-	
-	public String
-	getDisplayName();
-	
-	public String
-	getThumbURL();
-	
-	public boolean
-	isPlatformContent();
-	
-	public String
-	getPublisher();
-	
-	public byte[]
-	getImageBytes();
-	
-	public long
-	getSize();
-	
-	public boolean
-	canPlay();
-	
-		/**
-		 * Can return null 
-		 * @return
-		 */
-	
-	public TOTorrent
-	getTorrent();
-	
-		/**
-		 * Can return null if none associated with this share
-		 * @return
-		 */
-	
-	public DownloadManager
-	getDownloadManager();
-	
-		/**
-		 * Can return null if none associated with this share
-		 * @return
-		 */
-	
-	public DownloadUrlInfo 
-	getDownloadInfo();
-}
diff --git a/com/aelitis/azureus/buddy/chat/Chat.java b/com/aelitis/azureus/buddy/chat/Chat.java
deleted file mode 100644
index 6bd8295..0000000
--- a/com/aelitis/azureus/buddy/chat/Chat.java
+++ /dev/null
@@ -1,210 +0,0 @@
-package com.aelitis.azureus.buddy.chat;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.gudy.azureus2.core3.util.AEThread2;
-import org.gudy.azureus2.core3.util.SystemTime;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyMessageListener;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.instancemanager.AZInstanceManager;
-import com.aelitis.azureus.core.instancemanager.AZInstanceManagerFactory;
-import com.aelitis.azureus.core.security.CryptoHandler;
-import com.aelitis.azureus.core.security.CryptoManagerFactory;
-import com.aelitis.azureus.core.security.CryptoManagerKeyListener;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.plugins.dht.DHTPlugin;
-import com.aelitis.azureus.ui.swt.utils.SWTLoginUtils;
-import com.aelitis.azureus.util.LoginInfoManager;
-
-public class Chat implements VuzeBuddyMessageListener {
-	
-	Map discussions;
-	List listeners;
-	LoginInfoManager loginInfoManager;
-	
-	public Chat() {
-		discussions = new HashMap();
-		listeners = new ArrayList();
-		loginInfoManager = LoginInfoManager.getInstance();
-		VuzeBuddyManager.addMessageListener(this);
-		
-		CryptoManagerFactory.getSingleton().addKeyListener(
-			new CryptoManagerKeyListener()
-			{
-				public void
-				keyChanged(
-					CryptoHandler		handler )
-				{
-				}
-				
-				public void
-				keyLockStatusChanged(
-					CryptoHandler		handler )
-				{
-					if ( handler.isUnlocked()){
-						
-						new AEThread2( "Chat:check", true )
-						{
-							public void
-							run()
-							{
-								checkPersistentMessages();
-							}
-						}.start();
-					}
-				}
-			});
-	}
-	
-	protected void
-	checkPersistentMessages()
-	{
-		List to_check;	 
-	
-		synchronized (discussions) {
-			
-			to_check = new ArrayList( discussions.values());
-		}
-		
-		for (int i=0;i<to_check.size();i++){
-			
-			ChatDiscussion d = (ChatDiscussion)to_check.get(i);
-			
-			if ( d.checkPersistentMessages()){
-			
-				notifyListenersOfChat( d.getBuddy());
-			}
-		}
-	}
-	
-	public void
-	checkBuddy(
-		VuzeBuddy		buddy )
-	{
-		boolean	new_chat = false;
-		
-		ChatDiscussion result;
-		
-		boolean	check_persistent = CryptoManagerFactory.getSingleton().getECCHandler().isUnlocked();
-		
-		synchronized (discussions) {
-			result = (ChatDiscussion) discussions.get(buddy);
-			if(result == null) {
-				result = new ChatDiscussion( buddy, check_persistent );
-				discussions.put(buddy,result);
-				new_chat = true;
-			}
-		}
-		
-		if ( new_chat ){
-			
-			notifyListenersOfChat( buddy);
-		}
-	}
-	
-	public void messageRecieved(VuzeBuddy buddy, String senderPK, String namespace, long sentAt, Map message) {
-		if(namespace.equals("chat")) {
-			messageReceived(buddy, senderPK, sentAt, message);
-		}
-	}
-	
-	public ChatDiscussion getChatDiscussionFor(VuzeBuddy buddy) {
-		boolean	check_persistent = CryptoManagerFactory.getSingleton().getECCHandler().isUnlocked();
-
-		synchronized (discussions) {
-			ChatDiscussion result = (ChatDiscussion) discussions.get(buddy);
-			if(result == null) {
-				result = new ChatDiscussion( buddy, check_persistent );
-				discussions.put(buddy,result);
-			}
-			
-			return result;
-		}
-	}
-	
-	public void messageReceived(VuzeBuddy from,String fromPK, long sentAt, Map message) {
-		String text = new String((byte[])message.get("text"));
-		long originalTimeStamp = sentAt; // ((Long)message.get("timestamp")).longValue();
-		// System.out.println( "chat msg: recv=" + sentAt + ",sent=" + ((Long)message.get("timestamp")).longValue());
-		if(text != null) {
-			ChatDiscussion discussion = getChatDiscussionFor(from);
-			ChatMessage localMessage = new ChatMessage(fromPK,originalTimeStamp,SystemTime.getCurrentTime(),from.getDisplayName(),text);
-			discussion.addMessage(localMessage);
-			notifyListenersOfNewMessage(from,localMessage);
-		}
-	}
-	
-	public void sendMessage(final VuzeBuddy to,final String text) {
-		SWTLoginUtils.waitForLogin(new SWTLoginUtils.loginWaitListener() {
-			public void loginComplete() {
-				internalSendMessage(to, text);
-			}
-		});
-	}
-	
-	private void internalSendMessage(final VuzeBuddy to,final String text) {
-		AEThread2 sender = new AEThread2("message sender",true) {
-			public void run() {
-				try {
-					Map message = new HashMap();
-					long timeStamp = SystemTime.getCurrentTime();
-					
-						// try and use a reasonable originating timestamp
-					
-					if (AzureusCoreFactory.isCoreRunning()) {
-						timeStamp -= AzureusCoreFactory.getSingleton().getInstanceManager().getClockSkew();
-					}
-					
-					message.put("timestamp", new Long(timeStamp));
-					message.put("text", text);
-					to.sendBuddyMessage("chat", message);
-					ChatDiscussion discussion = getChatDiscussionFor(to);
-					
-					ChatMessage localMessage = new ChatMessage(null,timeStamp,timeStamp,loginInfoManager.getUserInfo().displayName,text);
-					discussion.addMessage(localMessage);
-					notifyListenersOfNewMessage(to,localMessage);
-				} catch(NotLoggedInException e) {
-					//User is not logged in...
-				}
-			}
-		};
-		sender.start();
-	}
-	
-	public void notifyListenersOfNewMessage(VuzeBuddy from,ChatMessage message) {
-		synchronized (listeners) {
-			for(int i = 0 ; i < listeners.size() ; i++) {
-				ChatListener listener = (ChatListener) listeners.get(i);
-				listener.newMessage(from,message);
-			}
-		}
-	}
-	
-	public void notifyListenersOfChat(VuzeBuddy buddy ) {
-		synchronized (listeners) {
-			for(int i = 0 ; i < listeners.size() ; i++) {
-				ChatListener listener = (ChatListener) listeners.get(i);
-				listener.updatedChat(buddy);
-			}
-		}
-	}
-	public void addChatListener(ChatListener listener) {
-		synchronized (listeners) {
-			listeners.add(listener);
-		}
-	}
-	
-	public void removeChatListener(ChatListener listener) {
-		synchronized (listeners) {
-			listeners.remove(listener);
-		}
-	}
-	
-
-}
diff --git a/com/aelitis/azureus/buddy/chat/ChatDiscussion.java b/com/aelitis/azureus/buddy/chat/ChatDiscussion.java
deleted file mode 100644
index 73f2819..0000000
--- a/com/aelitis/azureus/buddy/chat/ChatDiscussion.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package com.aelitis.azureus.buddy.chat;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-
-public class ChatDiscussion implements ChatMessageListener {
-	
-	VuzeBuddy	buddy;
-	List messages;
-	int unreadMessages;
-	DiscussionListener listener;
-	
-	public 
-	ChatDiscussion(
-		VuzeBuddy	_buddy,
-		boolean		_check_persistent ) 
-	{
-		buddy		= _buddy;
-		messages 	= new ArrayList();
-		
-		if ( _check_persistent ){
-			
-			List stored = buddy.getStoredChatMessages();
-			
-			for (int i=0;i<stored.size();i++){
-				
-				ChatMessage msg = (ChatMessage)stored.get(i);
-											
-				messages.add( msg );
-					
-				msg.addListener( this );
-				
-				unreadMessages++;
-			}
-		}
-	}
-	
-	protected boolean
-	checkPersistentMessages()
-	{
-		List stored = buddy.getStoredChatMessages();
-		
-		boolean	added = false;
-		
-		for (int i=0;i<stored.size();i++){
-			
-			ChatMessage msg = (ChatMessage)stored.get(i);
-			
-			synchronized(messages) {
-
-				if ( !messages.contains( msg )){
-				
-					added = true;
-					
-					messages.add( msg );
-						
-					msg.addListener( this );
-					
-					unreadMessages++;
-					
-					if(listener != null) {
-						listener.newMessage(msg);
-					}
-				}
-			}
-		}
-		
-		return( added );
-	}
-	
-	protected VuzeBuddy
-	getBuddy()
-	{
-		return( buddy );
-	}
-	
-	public void addMessage(ChatMessage message) {
-		synchronized(messages) {
-			if(!messages.contains(message)) {
-				unreadMessages++;
-				messages.add(message);
-				message.addListener( this );
-				if(listener != null) {
-					listener.newMessage(message);
-				}
-				
-				if ( !message.getRendered()){
-				
-					buddy.storeChatMessage( message );
-				}
-			}
-		}
-	}
-	
-	public void
-	rendered(
-		ChatMessage		message )
-	{
-		buddy.deleteChatMessage( message );
-	}
-	
-	public List getAllMessages() {
-		unreadMessages = 0;
-		return messages;
-	}
-	
-	public List getNewMessages() {
-		int nbMessages = messages.size();
-		List result = messages.subList(nbMessages - unreadMessages, nbMessages);
-		unreadMessages = 0;
-		return result;
-	}
-	
-	public void clearAllMessages() {
-		synchronized (messages) {
-			messages.clear();
-		}
-	}
-	
-	public void clearNewMessages() {
-		unreadMessages = 0;
-	}
-
-	public DiscussionListener getListener() {
-		return listener;
-	}
-
-	public void setListener(DiscussionListener listener) {
-		this.listener = listener;
-	}
-
-	public int getUnreadMessages() {
-		return unreadMessages;
-	}
-	
-	public int getNbMessages() {
-		return messages.size();
-	}
-
-}
diff --git a/com/aelitis/azureus/buddy/chat/ChatListener.java b/com/aelitis/azureus/buddy/chat/ChatListener.java
deleted file mode 100644
index 03a1bb2..0000000
--- a/com/aelitis/azureus/buddy/chat/ChatListener.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.aelitis.azureus.buddy.chat;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-
-public interface ChatListener {
-	
-	public void updatedChat( VuzeBuddy buddy );
-	
-	public void newMessage(VuzeBuddy from,ChatMessage message);
-
-}
diff --git a/com/aelitis/azureus/buddy/chat/ChatMessage.java b/com/aelitis/azureus/buddy/chat/ChatMessage.java
deleted file mode 100644
index 364b6c4..0000000
--- a/com/aelitis/azureus/buddy/chat/ChatMessage.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package com.aelitis.azureus.buddy.chat;
-
-import java.io.UnsupportedEncodingException;
-import java.util.*;
-
-import org.gudy.azureus2.core3.util.Debug;
-
-import com.aelitis.azureus.plugins.net.buddy.BuddyPluginBuddyMessage;
-
-public class ChatMessage {
-	
-	public static ChatMessage
-	deserialise(
-		BuddyPluginBuddyMessage		pm )
-	{
-		try{
-			Map	m = pm.getRequest();
-			
-			long	original_ts		= ((Long)m.get( "ot" )).longValue();
-			long	ts				= ((Long)m.get( "t" )).longValue();
-			String	sender			= new String((byte[])m.get( "se" ), "UTF-8" );
-			
-			byte[]	sender_pk_b		= (byte[])m.get( "sk" );
-			
-			String	sender_pk;
-			
-			if ( sender_pk_b == null ){
-			
-				sender_pk 	= null;
-				
-			}else{
-				
-				sender_pk	= new String( sender_pk_b, "UTF-8" );
-			}
-			
-			String	message			= new String((byte[])m.get( "msg" ), "UTF-8" );
-			
-			ChatMessage res = new ChatMessage( sender_pk, original_ts, ts, sender, message );
-			
-			res.setPersistentMessage( pm );
-			
-			return( res );
-			
-		}catch( Throwable e ){
-			
-			Debug.out( "Failed to decode chat message '" + pm + "'", e );
-			
-			return( null );
-		}
-	}
-	
-	private BuddyPluginBuddyMessage		persistent_msg;
-	
-	final long originalTimeStamp;
-	final long timestamp;
-	final String senderPK;
-	final String sender;
-	final String message;
-	
-	private boolean	rendered;
-	private List	listeners = new ArrayList();
-	
-	public ChatMessage(String senderPK,long originalTimeStamp,long timestamp, String sender, String message) {
-		super();
-		this.senderPK = senderPK;
-		this.originalTimeStamp = originalTimeStamp;
-		this.timestamp = timestamp;
-		this.sender = sender;
-		this.message = message;
-	}
-	
-	public void
-	setPersistentMessage(
-		BuddyPluginBuddyMessage		_pm )
-	{
-		persistent_msg	= _pm;
-	}
-	
-	public BuddyPluginBuddyMessage
-	getPersistentMessage()
-	{
-		return( persistent_msg );
-	}
-	
-	public long getTimestamp() {
-		return timestamp;
-	}
-
-	public long getOriginatorTimestamp()
-	{
-		return originalTimeStamp;
-	}
-	
-	public String getSender() {
-		return sender;
-	}
-
-	public String getMessage() {
-		return message;
-	}
-
-	public boolean isMe() {
-		return senderPK == null ||  senderPK.length()==0;
-	}
-	
-	public String
-	getSenderPK()
-	{
-		return( senderPK );
-	}
-	
-	public void
-	setRendered()
-	{
-		rendered	= true;
-		
-		for (int i=0;i<listeners.size();i++){
-			
-			try{
-				((ChatMessageListener)listeners.get(i)).rendered( this );
-				
-			}catch( Throwable e ){
-				
-				Debug.printStackTrace(e);
-			}
-		}
-	}
-	
-	public boolean
-	getRendered()
-	{
-		return( rendered );
-	}
-	
-	public void
-	addListener(
-		ChatMessageListener		l )
-	{
-		listeners.add( l );
-	}
-	
-	public Map
-	toMap()
-	{
-		Map	m = new HashMap();
-		
-		m.put( "ot", new Long( originalTimeStamp ));
-		m.put( "t", new Long( timestamp ));
-		
-		try{
-			m.put( "se", sender.getBytes( "UTF-8" ));
-			
-			if ( senderPK != null ){
-			
-				m.put( "sk", senderPK.getBytes( "UTF-8" ));
-			}
-			
-			m.put( "msg", message.getBytes( "UTF-8" ));
-			
-		}catch( UnsupportedEncodingException e ){
-			
-			Debug.out(e);
-		}
-		
-		return( m );
-		
-	}
-	
-	public boolean equals(Object o) {
-		if(o instanceof ChatMessage) {
-			ChatMessage other = (ChatMessage) o;
-			return other.originalTimeStamp == this.originalTimeStamp;
-		}
-		return false;
-	}
-}
diff --git a/com/aelitis/azureus/buddy/chat/ChatMessageListener.java b/com/aelitis/azureus/buddy/chat/ChatMessageListener.java
deleted file mode 100644
index 78033ce..0000000
--- a/com/aelitis/azureus/buddy/chat/ChatMessageListener.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Created on Jun 27, 2008
- * Created by Paul Gardner
- * 
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-
-package com.aelitis.azureus.buddy.chat;
-
-public interface 
-ChatMessageListener 
-{
-	public void
-	rendered(
-		ChatMessage		message );
-}
diff --git a/com/aelitis/azureus/buddy/chat/DiscussionListener.java b/com/aelitis/azureus/buddy/chat/DiscussionListener.java
deleted file mode 100644
index dc3f596..0000000
--- a/com/aelitis/azureus/buddy/chat/DiscussionListener.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.aelitis.azureus.buddy.chat;
-
-import com.aelitis.azureus.plugins.net.buddy.BuddyPluginAZ2.chatMessage;
-
-public interface DiscussionListener {
-
-	public void newMessage(ChatMessage message);
-}
diff --git a/com/aelitis/azureus/buddy/impl/VuzeBuddyFakeImpl.java b/com/aelitis/azureus/buddy/impl/VuzeBuddyFakeImpl.java
deleted file mode 100644
index 18929b5..0000000
--- a/com/aelitis/azureus/buddy/impl/VuzeBuddyFakeImpl.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * Created on May 9, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.buddy.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Buddy Object not linked to an buddypluginbuddy
- * 
- * @author TuxPaper
- * @created May 9, 2008
- *
- */
-public class VuzeBuddyFakeImpl
-	extends VuzeBuddyImpl
-{
-	private List pks = new ArrayList();
-	
-	/**
-	 * 
-	 */
-	protected VuzeBuddyFakeImpl() {
-	}
-
-	/**
-	 * @param mapFakeBuddy
-	 */
-	public VuzeBuddyFakeImpl(Map mapFakeBuddy) {
-		loadFromMap(mapFakeBuddy);
-	}
-
-	public void addPublicKey(String pk) {
-		if (!pks.contains(pk)) {
-			pks.add(pk);
-		}
-	}
-	
-	// @see com.aelitis.azureus.buddy.impl.VuzeBuddyImpl#removePublicKey(java.lang.String)
-	public void removePublicKey(String pk) {
-		pks.remove(pk);
-	}
-	
-	// @see com.aelitis.azureus.buddy.impl.VuzeBuddyImpl#getPublicKeys()
-	public String[] getPublicKeys() {
-		return (String[]) pks.toArray(new String[pks.size()]);
-	}
-	
-	public void setDisplayName(String displayName) {
-		// like super, except no trigger
-		if (displayName == null) {
-			displayName = "";
-		}
-		if (displayName.equals(this.displayName)){
-			return;
-		}
-		this.displayName = displayName;
-	}
-	
-	public String toDebugString() {
-		return "Fake" + super.toDebugString(); 
-	}
-}
diff --git a/com/aelitis/azureus/buddy/impl/VuzeBuddyImpl.java b/com/aelitis/azureus/buddy/impl/VuzeBuddyImpl.java
deleted file mode 100644
index 0f1a626..0000000
--- a/com/aelitis/azureus/buddy/impl/VuzeBuddyImpl.java
+++ /dev/null
@@ -1,758 +0,0 @@
-/**
- * Created on Apr 14, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.buddy.impl;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.*;
-
-import org.gudy.azureus2.core3.util.*;
-
-import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.activities.VuzeActivitiesEntryContentShare;
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.VuzeBuddyListener;
-import com.aelitis.azureus.buddy.VuzeShareable;
-import com.aelitis.azureus.buddy.chat.ChatMessage;
-import com.aelitis.azureus.core.subs.Subscription;
-import com.aelitis.azureus.core.subs.SubscriptionManagerFactory;
-import com.aelitis.azureus.core.util.CopyOnWriteList;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPlugin;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPluginBuddy;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPluginBuddyMessage;
-import com.aelitis.azureus.ui.utils.ImageBytesDownloader;
-import com.aelitis.azureus.util.*;
-
-/**
- * BuddyPluginBuddy plus some vuze specific stuff
- * 
- * @author TuxPaper
- * @created Apr 14, 2008
- *
- */
-public class VuzeBuddyImpl
-	implements VuzeBuddy
-{
-	protected String displayName;
-
-	private String loginID;
-
-	private String code;
-
-	private long lastUpdated;
-
-	private long createdOn;
-
-	private String avatarURL;
-
-	private CopyOnWriteList<BuddyPluginBuddy> pluginBuddies = new CopyOnWriteList<BuddyPluginBuddy>();
-
-	private AEMonitor mon_pluginBuddies = new AEMonitor("pluginBuddies");
-
-	private ArrayList<VuzeBuddyListener> listeners = new ArrayList<VuzeBuddyListener>(0);
-
-	protected VuzeBuddyImpl(String publicKey) {
-		addPublicKey(publicKey);
-	}
-
-	protected VuzeBuddyImpl() {
-	}
-
-	public void loadFromMap(Map mapNewBuddy) {
-		if (mapNewBuddy == null) {
-			return;
-		}
-		setDisplayName(MapUtils.getMapString(mapNewBuddy, "display-name", ""
-				+ mapNewBuddy.hashCode()));
-		setLoginID(MapUtils.getMapString(mapNewBuddy, "login-id", ""
-				+ mapNewBuddy.hashCode()));
-
-		List<String> pksAdded = new ArrayList();
-		List pkList = MapUtils.getMapList(mapNewBuddy, "pks",
-				Collections.EMPTY_LIST);
-		for (Iterator iter = pkList.iterator(); iter.hasNext();) {
-			Object o = iter.next();
-			String pk = null;
-			if (o instanceof byte[]) {
-				try {
-					pk = new String((byte[]) o, "utf-8");
-				} catch (UnsupportedEncodingException e) {
-				}
-			} else if (o instanceof String) {
-				pk = (String) o;
-			}
-			if (pk != null) {
-				addPublicKey(pk);
-				pksAdded.add(pk);
-			}
-		}
-
-		// Remove plugin buddies that have not been (re-)addded to the list
-		for (BuddyPluginBuddy pluginBuddy : pluginBuddies.getList()) {
-			String pk = pluginBuddy.getPublicKey();
-			if (pk != null && !pksAdded.contains(pk)) {
-				removePublicKey(pk);
-			}
-		}
-
-		
-		// first try to get the avatar via raw bytes
-		byte[] newAvatar = MapUtils.getMapByteArray(mapNewBuddy, "avatar", null);
-		if (newAvatar != null) {
-			setAvatar(newAvatar);
-		}
-
-		// start of day, existing url none and we have one, just use it and assume corresponds
-		
-		String newAvatarURL = MapUtils.getMapString(mapNewBuddy, "avatar.url", null);
-
-		if ( avatarURL == null && hasAvatar()){
-			
-			avatarURL = newAvatarURL;
-		}else{
-		
-			if (!StringCompareUtils.equals(newAvatarURL, avatarURL) || !hasAvatar()) {
-				avatarURL = newAvatarURL;
-				if (avatarURL != null) {
-					ImageBytesDownloader.loadImage(avatarURL,
-							new ImageBytesDownloader.ImageDownloaderListener() {
-								public void imageDownloaded(byte[] image) {
-									VuzeBuddyManager.log("Got new avatar! " + toDebugString());
-									setAvatar(image);
-								}
-							});
-				}
-			}
-		}
-
-		setCode(MapUtils.getMapString(mapNewBuddy, "code", null));
-		setCreatedOn(MapUtils.getMapLong(mapNewBuddy, "created-on", 0));
-	}
-
-	public Map toMap() {
-		Map map = new HashMap();
-		map.put("display-name", displayName);
-		map.put("login-id", loginID);
-		map.put("code", code);
-		map.put("created-on", new Long(createdOn));
-
-		List pks = Arrays.asList(getPublicKeys());
-		map.put("pks", pks);
-
-		map.put("avatar.url", avatarURL);
-
-		return map;
-	}
-
-	public String getDisplayName() {
-		return displayName;
-	}
-
-	public void setDisplayName(String displayName) {
-		if (displayName == null) {
-			displayName = "";
-		}
-		if (displayName.equals(this.displayName)) {
-			return;
-		}
-		this.displayName = displayName;
-		VuzeBuddyManager.triggerOrderChangedListener();
-	}
-
-	public String getLoginID() {
-		return loginID;
-	}
-
-	public void setLoginID(String loginID) {
-		this.loginID = loginID;
-	}
-
-	public long getLastUpdated() {
-		return lastUpdated;
-	}
-
-	public void setLastUpdated(long lastUpdated) {
-		boolean trigger = (this.lastUpdated > 0);
-		this.lastUpdated = lastUpdated;
-		if (trigger) {
-			VuzeBuddyManager.triggerChangeListener(this);
-		}
-	}
-
-	public byte[] getAvatar() {
-		try {
-			File file = getAvatarFile();
-			if (file.exists()) {
-				FileInputStream fis = new FileInputStream(file);
-				
-				try{
-					return FileUtil.readInputStreamAsByteArray(fis);
-					
-				}finally{
-					
-					fis.close();
-				}
-			}
-		} catch (Throwable t) {
-		}
-
-		return null;
-	}
-	
-	private File getAvatarFile() {
-		// use hash of login id in case it has special chars
-		return new File(SystemProperties.getUserPath(), "friends"
-				+ File.separator + getLoginID().hashCode() + ".ico");
-	}
-
-	private boolean hasAvatar() {
-		return getAvatarFile().exists();
-	}
-
-	public void setAvatar(byte[] avatar) {
-		File file = getAvatarFile();
-		FileUtil.writeBytesAsFile(file.getAbsolutePath(), avatar);
-
-		VuzeBuddyManager.triggerChangeListener(this);
-	}
-
-	public boolean isOnline(boolean is_connected) {
-		for (Iterator<BuddyPluginBuddy> iter = pluginBuddies.iterator(); iter.hasNext();) {
-			BuddyPluginBuddy pluginBuddy = iter.next();
-			if (pluginBuddy.isOnline(is_connected)) {
-
-				if (pluginBuddy.getOnlineStatus() != BuddyPlugin.STATUS_APPEAR_OFFLINE) {
-
-					return (true);
-				}
-			}
-		}
-
-		return false;
-	}
-
-	public int getVersion() {
-		int version = VERSION_INITIAL;
-
-		for (Iterator<BuddyPluginBuddy> iter = pluginBuddies.iterator(); iter.hasNext();) {
-			BuddyPluginBuddy pluginBuddy = iter.next();
-
-			version = Math.max(pluginBuddy.getVersion(), version);
-		}
-
-		return version;
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddy#addPublicKey()
-	public void addPublicKey(String pk) {
-		// We add public keys by adding BuddyPluginBuddy
-
-		BuddyPluginBuddy pluginBuddy = VuzeBuddyManager.getBuddyPluginBuddyForVuze(pk);
-
-		mon_pluginBuddies.enter();
-		try {
-
-			if (pluginBuddy != null && !pluginBuddies.contains(pluginBuddy)){
-				
-					// check consistency of new buddy
-				
-				if ( pluginBuddies.size() > 0 ){
-					
-					BuddyPluginBuddy template_buddy = pluginBuddies.getList().get(0);
-					
-					Set<String> template_loc_cat = template_buddy.getLocalAuthorisedRSSCategories();
-					
-					pluginBuddy.setLocalAuthorisedRSSCategories( template_loc_cat );
-				}
-				
-				pluginBuddies.add(pluginBuddy);
-			}
-
-		} finally {
-			mon_pluginBuddies.exit();
-		}
-
-		VuzeBuddyManager.linkPKtoBuddy(pk, this);
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddy#removePublicKey(java.lang.String)
-	public void removePublicKey(String pk) {
-		// our public key list is actually a BuddyPluginBuddy list, so find
-		// it in our list and remove it
-		mon_pluginBuddies.enter();
-		try {
-			for (Iterator<BuddyPluginBuddy> iter = pluginBuddies.iterator(); iter.hasNext();) {
-				BuddyPluginBuddy pluginBuddy = iter.next();
-				if (pluginBuddy.getPublicKey().equals(pk)) {
-					iter.remove();
-					if (pluginBuddy.getSubsystem() == BuddyPlugin.SUBSYSTEM_AZ3) {
-						VuzeBuddyManager.log("Remove pk " + pk);
-						pluginBuddy.remove();
-					} else {
-						VuzeBuddyManager.log("Can't remove pk as it's not az3: " + pk);
-					}
-				}
-			}
-		} finally {
-			mon_pluginBuddies.exit();
-		}
-	}
-
-	public String[] getPublicKeys() {
-		mon_pluginBuddies.enter();
-		try {
-			String[] ret = new String[pluginBuddies.size()];
-			int x = 0;
-
-			for (Iterator<BuddyPluginBuddy> iter = pluginBuddies.iterator(); iter.hasNext();) {
-				BuddyPluginBuddy pluginBuddy = iter.next();
-				
-				ret[x++] = pluginBuddy.getPublicKey();
-			}
-			return ret;
-		} finally {
-			mon_pluginBuddies.exit();
-		}
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddy#sendActivity(com.aelitis.azureus.util.VuzeActivitiesEntry)
-	public void sendActivity(VuzeActivitiesEntry entry)
-			throws NotLoggedInException {
-		BuddyPluginBuddy[] buddies = (BuddyPluginBuddy[]) pluginBuddies.toArray(new BuddyPluginBuddy[0]);
-		VuzeBuddyManager.sendActivity(entry, buddies);
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddy#sendPayloadMap(java.util.Map)
-	public void sendPayloadMap(Map map)
-			throws NotLoggedInException {
-		BuddyPluginBuddy[] buddies = (BuddyPluginBuddy[]) pluginBuddies.toArray(new BuddyPluginBuddy[0]);
-		VuzeBuddyManager.sendPayloadMap(map, buddies);
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddy#sendPayloadMap(java.lang.String, java.util.Map)
-	// @see com.aelitis.azureus.buddy.VuzeBuddy#sendBuddyMessageMap(java.lang.String, java.util.Map)
-	public void sendBuddyMessage(String namespace, Map map)
-			throws NotLoggedInException {
-		HashMap containerMap = new HashMap(3);
-		containerMap.put("namespace", namespace);
-		containerMap.put(VuzeBuddyManager.VUZE_MESSAGE_TYPE,
-				VuzeBuddyManager.VMT_BUDDY_MESSAGE);
-		containerMap.put("map", map);
-		BuddyPluginBuddy[] buddies = (BuddyPluginBuddy[]) pluginBuddies.toArray(new BuddyPluginBuddy[0]);
-		VuzeBuddyManager.sendPayloadMap(containerMap, buddies);
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddy#shareDownload(com.aelitis.azureus.ui.swt.currentlyselectedcontent.CurrentContent, java.lang.String)
-	public void shareDownload(VuzeShareable content, String message)
-			throws NotLoggedInException {
-		if (content == null) {
-			return;
-		}
-
-		VuzeActivitiesEntryContentShare entry;
-		entry = new VuzeActivitiesEntryContentShare(content, message);
-		entry.setBuddyID(LoginInfoManager.getInstance().getUserInfo().userName);
-
-		sendActivity(entry);
-	}
-
-	public void tellBuddyToSyncUp()
-			throws NotLoggedInException {
-		Map map = new HashMap();
-		map.put(VuzeBuddyManager.VUZE_MESSAGE_TYPE, VuzeBuddyManager.VMT_BUDDYSYNC);
-
-		sendPayloadMap(map);
-	}
-
-	public String getCode() {
-		return code;
-	}
-
-	public void setCode(String code) {
-		this.code = code;
-	}
-
-	public String getProfileAHREF(String referer) {
-		return getProfileAHREF(referer, false);
-	}
-
-	public String getProfileAHREF(String referer, boolean useImage) {
-		StringBuffer buf = new StringBuffer();
-
-		buf.append("<A HREF=\"");
-		buf.append(getProfileUrl(referer));
-		buf.append("\" TITLE=\"");
-		buf.append(displayName);
-		if (!loginID.equals(displayName)) {
-			buf.append(" (");
-			buf.append(loginID);
-			buf.append(")");
-		}
-		buf.append("\">");
-		if (useImage) {
-			buf.append("%0 ");
-		}
-		buf.append(displayName);
-		buf.append("</A>");
-		return buf.toString();
-	}
-
-	public String getProfileUrl(String referer) {
-		return( ConstantsVuze.getDefaultContentNetwork().getProfileService(getLoginID(), referer));
-	}
-
-	// @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
-	public int compare(Object arg0, Object arg1) {
-		if (!(arg0 instanceof VuzeBuddy) || !(arg1 instanceof VuzeBuddy)) {
-			return 0;
-		}
-
-		String c0 = ((VuzeBuddy) arg0).getDisplayName();
-		String c1 = ((VuzeBuddy) arg1).getDisplayName();
-
-		if (c0 == null) {
-			c0 = "";
-		}
-		if (c1 == null) {
-			c1 = "";
-		}
-		return c0.compareToIgnoreCase(c1);
-	}
-
-	// @see java.lang.Comparable#compareTo(java.lang.Object)
-	public int compareTo(Object arg0) {
-		return compare(this, arg0);
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddy#setCreatedOn(long)
-	public void setCreatedOn(long createdOn) {
-		this.createdOn = createdOn;
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddy#getCreatedOn()
-	public long getCreatedOn() {
-		return createdOn;
-	}
-
-	// @see com.aelitis.azureus.buddy.VuzeBuddy#toDebugString()
-	public String toDebugString() {
-		return "Buddy {" + loginID + "}";
-	}
-
-	public void addListener(VuzeBuddyListener l) {
-		if (!listeners.contains(l)) {
-			listeners.add(l);
-		}
-	}
-
-	public void removeListener(VuzeBuddyListener l) {
-		listeners.remove(l);
-	}
-
-	public VuzeBuddyListener[] getListeners() {
-		return (VuzeBuddyListener[]) listeners.toArray(new VuzeBuddyListener[0]);
-	}
-
-	public int
-	getStoredChatMessageCount()
-	{
-		Iterator<BuddyPluginBuddy> it = pluginBuddies.iterator();
-
-		int	res = 0;
-
-		while (it.hasNext()) {
-
-			BuddyPluginBuddy pluginBuddy = it.next();
-
-			List<BuddyPluginBuddyMessage> msgs = pluginBuddy.retrieveMessages(BuddyPlugin.MT_V3_CHAT);
-
-			res += msgs.size();
-		}
-
-		return( res );
-	}
-	
-	public List<ChatMessage>
-	getStoredChatMessages()
-	{
-		Iterator<BuddyPluginBuddy> it = pluginBuddies.iterator();
-
-		List<ChatMessage> result = new ArrayList<ChatMessage>();
-
-		while (it.hasNext()) {
-
-			BuddyPluginBuddy pluginBuddy = it.next();
-
-			List<BuddyPluginBuddyMessage> msgs = pluginBuddy.retrieveMessages(BuddyPlugin.MT_V3_CHAT);
-
-			for (int i = 0; i < msgs.size(); i++) {
-
-				try {
-					BuddyPluginBuddyMessage msg = (BuddyPluginBuddyMessage) msgs.get(i);
-
-					ChatMessage cm = ChatMessage.deserialise(msg);
-
-					if (cm != null) {
-
-						result.add(cm);
-					}
-				} catch (Throwable e) {
-
-				}
-			}
-		}
-
-		// TODO: sort by timestamp
-
-		return (result);
-	}
-
-	public void
-	storeChatMessage(
-		ChatMessage		msg )
-	{
-		String sender_pk = msg.getSenderPK();
-
-		if (sender_pk != null) {
-
-			BuddyPluginBuddy pluginBuddy = VuzeBuddyManager.getBuddyPluginBuddyForVuze(sender_pk);
-
-			if (pluginBuddy == null) {
-
-				VuzeBuddyManager.log( "Can't persist message for " + sender_pk + ", buddy not found" );
-
-			} else {
-
-				BuddyPluginBuddyMessage pm = pluginBuddy.storeMessage(
-						BuddyPlugin.MT_V3_CHAT, msg.toMap());
-
-				if (pm != null) {
-
-					msg.setPersistentMessage(pm);
-				}
-			}
-		}
-	}
-
-	public void
-	deleteChatMessage(
-		ChatMessage		msg )
-	{
-		BuddyPluginBuddyMessage pm = msg.getPersistentMessage();
-
-		if (pm != null) {
-
-			pm.delete();
-		}
-	}
-	
-	public Set<String>
-	getSubscribableCategories()
-	{
-		Iterator<BuddyPluginBuddy> it = pluginBuddies.iterator();
-
-		Set<String> result = new HashSet<String>();
-
-		while (it.hasNext()){
-
-			BuddyPluginBuddy pluginBuddy = it.next();
-
-			Set<String> x = pluginBuddy.getRemoteAuthorisedRSSCategories();
-			
-			if ( x != null ){
-				
-				result.addAll(x);
-			}
-		}
-		
-		return( result );
-	}
-	
-	public boolean
-	canSubscribeToCategory()
-	{
-		Iterator<BuddyPluginBuddy> it = pluginBuddies.iterator();
-
-		while (it.hasNext()){
-
-			BuddyPluginBuddy pluginBuddy = it.next();
-
-			Set<String> x = pluginBuddy.getRemoteAuthorisedRSSCategories();
-				
-			if ( x != null && x.size() > 0 ){
-	
-				return( true );
-			}
-		}
-		
-		return( false );
-	}
-	
-	public boolean
-	isSubscribedToCategory(
-		String		category )
-	{
-		Iterator<BuddyPluginBuddy> it = pluginBuddies.iterator();
-
-		while (it.hasNext()){
-
-			BuddyPluginBuddy pluginBuddy = it.next();
-
-			if ( pluginBuddy.isRemoteRSSCategoryAuthorised( category )){
-				
-				Subscription	subs = lookupSubscription( pluginBuddy, category );
-				
-				if ( subs == null ){
-					
-					return( false );
-				}
-			}
-		}
-		
-		return( true );
-	}
-	
-	public void
-	setSubscribedToCategory(
-		String		category,
-		boolean		subscribed )
-	{
-		Iterator<BuddyPluginBuddy> it = pluginBuddies.iterator();
-
-		while (it.hasNext()){
-
-			BuddyPluginBuddy pluginBuddy = it.next();
-
-			Subscription	subs = lookupSubscription( pluginBuddy, category );
-
-			if ( !subscribed ){
-				
-				if ( subs != null ){
-				
-					subs.remove();
-				}
-			}else{
-				
-				if ( subs == null ){
-		
-					if ( pluginBuddy.isRemoteRSSCategoryAuthorised( category )){
-				
-						try{
-							pluginBuddy.subscribeToCategory( category );
-							
-						}catch( Throwable e ){
-							
-							Debug.out( e );
-						}
-					}
-				}
-			}
-		}
-	}
-	
-	protected Subscription
-	lookupSubscription(
-		BuddyPluginBuddy		buddy,
-		String					cat )
-	{
-		Subscription[] subs = SubscriptionManagerFactory.getSingleton().getSubscriptions();
-		
-		for ( Subscription s: subs ){
-			
-			if ( buddy.isSubscribedToCategory( cat, s.getCreatorRef())){
-				
-				return( s );
-			}
-		}
-		
-		return( null );
-	}
-	
-	public Set<String>
-	getPublishedCategories()
-	{
-		Iterator<BuddyPluginBuddy> it = pluginBuddies.iterator();
-
-		Set<String> result = new HashSet<String>();
-
-		while (it.hasNext()){
-
-			BuddyPluginBuddy pluginBuddy = it.next();
-
-			Set<String> x = pluginBuddy.getLocalAuthorisedRSSCategories();
-			
-			if ( x != null ){
-				
-				result.addAll(x);
-			}
-		}
-		
-		return( result );
-	}
-	
-	public boolean
-	isPublishedCategory(
-		String		category )
-	{
-		Iterator<BuddyPluginBuddy> it = pluginBuddies.iterator();
-
-		while (it.hasNext()){
-
-			BuddyPluginBuddy pluginBuddy = it.next();
-
-			if ( !pluginBuddy.isLocalRSSCategoryAuthorised(category)){
-				
-				return( false );
-			}
-		}
-		
-		return( true );
-	}
-	
-	public void
-	setPublishedCategory(
-		String		category,
-		boolean		published )
-	{
-		Iterator<BuddyPluginBuddy> it = pluginBuddies.iterator();
-
-		while (it.hasNext()){
-
-			BuddyPluginBuddy pluginBuddy = it.next();
-
-			if ( published ){
-			
-				pluginBuddy.addLocalAuthorisedRSSCategory( category );
-				
-			}else{
-				
-				pluginBuddy.removeLocalAuthorisedRSSCategory( category );				
-			}
-		}
-	}
-	
-	public boolean
-	canSetPublishedCategory(
-		String		category )
-	{
-		return( VuzeBuddyManager.canSetPublishedCategory( category ));
-	}
-}
diff --git a/com/aelitis/azureus/buddy/impl/VuzeBuddyManager.java b/com/aelitis/azureus/buddy/impl/VuzeBuddyManager.java
deleted file mode 100644
index 92959e0..0000000
--- a/com/aelitis/azureus/buddy/impl/VuzeBuddyManager.java
+++ /dev/null
@@ -1,1813 +0,0 @@
-/**
- * Created on Apr 14, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.buddy.impl;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.*;
-
-import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.*;
-
-import com.aelitis.azureus.activities.*;
-import com.aelitis.azureus.buddy.*;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.crypto.VuzeCryptoException;
-import com.aelitis.azureus.core.crypto.VuzeCryptoListener;
-import com.aelitis.azureus.core.crypto.VuzeCryptoManager;
-import com.aelitis.azureus.core.messenger.PlatformAuthorizedSender;
-import com.aelitis.azureus.core.messenger.PlatformMessenger;
-import com.aelitis.azureus.core.messenger.config.*;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.plugins.net.buddy.*;
-import com.aelitis.azureus.ui.UIFunctions;
-import com.aelitis.azureus.ui.UIFunctionsManager;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentV3;
-import com.aelitis.azureus.util.*;
-import com.aelitis.azureus.util.LoginInfoManager.LoginInfo;
-
-import org.gudy.azureus2.plugins.Plugin;
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.utils.StaticUtilities;
-
-/**
- * General Management of Vuze Buddies.
- * <P>
- * requires one init() call before being used
- * 
- * @author TuxPaper
- * @created Apr 14, 2008
- *
- */
-public class VuzeBuddyManager
-{
-	private static final int SEND_P2P_TIMEOUT = 1000 * 60 * 3;
-
-	protected static final boolean ALLOW_ONLY_AZ3 = true;
-
-	private static final String SAVE_FILENAME = "v3.Friends.dat";
-	
-	public static final String VUZE_MESSAGE_TYPE = "VuzeMessageType";
-
-	public static final String VMT_CHECKINVITES = "CheckInvites";
-
-	public static final String VMT_BUDDYACCEPT = "BuddyAccept";
-
-	public static final String VMT_ACTIVITYENTRY = "ActivityEntry";
-
-	public static final String VMT_BUDDY_MESSAGE = "BuddyMessage";
-
-	public static final String VMT_BUDDYSYNC = "BuddySync";
-
-	private static final String UNKNOWN_MSG_TYPE = "Unknown Message Type"; 
-
-	private static BuddyPlugin buddyPlugin = null;
-
-	private static List buddyList = new ArrayList();
-
-	private static AEMonitor buddy_mon = new AEMonitor("buddy list/map");
-
-	private static Map mapPKtoVuzeBuddy = new HashMap();
-
-	private static VuzeBuddyCreator vuzeBuddyCreator;
-
-	private static List listeners = new ArrayList();
-
-	private static boolean saveDelayed = true;
-
-	private static File configDir;
-	
-	private static ArrayList messageListeners = new ArrayList(1);
-
-	
-	private static BuddyPluginBuddyMessageListener buddy_message_handler_listener = 
-		new BuddyPluginBuddyMessageListener()
-		{
-			private Set		pending_messages 	= new HashSet();
-			private int		consecutive_fails	= 0;
-			private long	last_send_attempt;
-			
-			public void
-			messageQueued(
-				BuddyPluginBuddyMessage		message )
-			{			
-			}
-			
-			public void
-			messageDeleted(
-				BuddyPluginBuddyMessage		message )
-			{
-			}
-			
-			public boolean
-			deliverySucceeded(
-				BuddyPluginBuddyMessage		message,
-				Map							reply )
-			{
-				if ( message.getSubsystem() != BuddyPlugin.SUBSYSTEM_AZ3 ){
-					
-					return( true );
-				}
-				
-				VuzeBuddyManager.log("REPLY REC "
-					+ (message.getBuddy() == null ? "" : message.getBuddy().getName())
-					+ JSONUtils.encodeToJSON(reply));
-				
-				String response = MapUtils.getMapString(reply, "response", "");
-				
-				if (response.equals(UNKNOWN_MSG_TYPE)) {
-					try {
-						Map map = message.getRequest();
-						VuzeBuddyManager.log("  " + response + "; "
-								+ MapUtils.getMapString(map, "VuzeMessageType", "null"));
-					} catch (Throwable t) {
-					}
-					// fake that we handled it..
-					return true;
-				}
-				
-				if ( !response.toLowerCase().equals("ok")){
-					
-					sendViaRelayServer( message );
-					
-						// false here will re-attempt this call later (and keep message around)
-					// when the sendViaRelayServer succeeds, the message will be removed.
-					// If it fails, the message will be retried later
-					
-					return( false );
-				}
-				
-				return( true );
-			}
-			
-			public void
-			deliveryFailed(
-				BuddyPluginBuddyMessage		message,
-				BuddyPluginException		cause )
-			{
-				if ( message.getSubsystem() != BuddyPlugin.SUBSYSTEM_AZ3 ){
-					
-					return;
-				}
-				
-				BuddyPluginBuddy buddy = message.getBuddy();
-				
-				VuzeBuddyManager.log("SEND FAILED " + buddy.getPublicKey() + "\n" + cause);
-
-				if ( !message.isDeleted()){
-				
-					sendViaRelayServer( message );
-				}
-			}
-			
-			protected void
-			sendViaRelayServer(
-				BuddyPluginBuddyMessage	message )
-			{
-					// we can get in here > once for same message in theory if relay
-					// server dispatch slow and async the buddy plugin retries delivery
-				
-					// so, all messages will auto-retry entry here every n minutes. so this is
-					// a reasonable place to rate limit on failure
-				
-				synchronized( pending_messages ){
-					
-					if ( pending_messages.contains( message )){
-						
-						return;
-					}
-					
-					long now = SystemTime.getCurrentTime();
-					
-					if ( last_send_attempt > now ){
-						
-						last_send_attempt = now;
-					}
-										
-					if ( consecutive_fails > 1 ){
-					
-						long delay = 5*60*1000;
-						
-						final int MAX_DELAY =  4*60*60*1000;
-						
-						for (int i=2;i<=consecutive_fails;i++){
-							
-							delay <<= 1;
-							
-							if ( delay > MAX_DELAY){
-								
-								delay = MAX_DELAY;
-								
-								break;
-							}
-						}
-						
-						long delay_remaining = delay - (now - last_send_attempt);
-						
-						if ( delay_remaining > 0 ){
-							
-							VuzeBuddyManager.log( "RELAY: deferring put due to repeated failures (retry in " + delay_remaining + ")" );
-
-							return;
-						}
-					}
-					
-					pending_messages.add( message );
-					
-					last_send_attempt = now;
-				}
-				
-				PlatformRelayMessenger.put(
-					message,
-					500,
-					new PlatformRelayMessenger.putListener()
-					{
-						public void
-						putOK(
-							BuddyPluginBuddyMessage		message )
-						{
-							try{
-								
-								try {
-									BuddyPluginBuddy buddy = message.getBuddy();
-									buddy.setMessagePending();
-									log("Sending YGM to " + buddy.getName());
-								} catch (Exception e) {
-									log(e);
-								}
-							
-								message.delete();
-								
-							}finally{
-								
-								synchronized( pending_messages ){
-									
-									pending_messages.remove( message );
-									
-									consecutive_fails	= 0;
-									
-									VuzeBuddyManager.log( "RELAY: put ok - resetting consec fails" );
-								}
-							}
-						}
-						
-						public void
-						putFailed(
-							BuddyPluginBuddyMessage		message,
-							Throwable					cause )
-						{
-							synchronized( pending_messages ){
-								
-								pending_messages.remove( message );
-								
-								consecutive_fails++;
-								
-								VuzeBuddyManager.log( "RELAY: put failed - " + Debug.getNestedExceptionMessage( cause ) + ", consec fails=" + consecutive_fails );
-							}
-						}
-					});
-			}
-		};
-
-	private static VuzeCryptoListener vuzeCryptoListener = new VuzeCryptoListener() {
-		
-		private AESemaphore warning_sem = new AESemaphore( "VBM:pwwarning", 1 );
-		
-		private int 	consec_bad_passwords;
-		private long	first_bad_password	= -1;
-		private long	last_warning		= -1;
-		
-		public void sessionPasswordIncorrect() {
-			
-			VuzeBuddyManager.log("Incorrect Password!");
-			
-			if ( org.gudy.azureus2.core3.util.Constants.isCVSVersion()){
-				
-				long	time = SystemTime.getMonotonousTime();
-				
-				if ( first_bad_password == -1 ){
-					
-					first_bad_password = time;
-				}
-				
-				consec_bad_passwords++;
-				
-				VuzeBuddyManager.log( "Consecutive bad passwords = " + consec_bad_passwords );
-				
-				if ( 	time - first_bad_password > 10*60*1000 &&
-						consec_bad_passwords >= 3 ){
-					
-					if  ( 	( last_warning == -1 || time - last_warning > 60*60*1000 ) &&
-							warning_sem.getValue() > 0 ){
-					
-						last_warning = time;
-						
-						new AEThread2( "VBM:warning", true )
-						{
-							public void
-							run()
-							{
-								try{
-									warning_sem.reserve();
-								
-									StaticUtilities.promptUser(
-											"Password Error",
-											"There is a problem with system password management. Please logout and login again.\nIf this problem persists refer to the user forums.",
-											new String[]{ "OK" },
-											0 );
-								}finally{
-									
-									warning_sem.release();
-								}
-							}
-						}.start();
-					}
-				}
-			}
-		}
-
-		
-		public void sessionPasswordCorrect() {
-		
-			VuzeBuddyManager.log("Correct Password!");
-			
-			consec_bad_passwords		= 0;
-			first_bad_password			= -1;
-		}
-		
-		public char[] getSessionPassword(String reason)
-				throws VuzeCryptoException {
-			VuzeBuddyManager.log("PW Request: " + reason + "; "
-					+ Debug.getCompressedStackTrace());
-			throw new VuzeCryptoException("Not Logged In", null);
-		}
-	};
-	
-	private static ILoginInfoListener loginInfoListener = new ILoginInfoListener() {
-		public void loginUpdate(final LoginInfo info, boolean isNewLoginID) {
-			loginUpdateTriggered(info, isNewLoginID);
-		}
-
-		public void avatarURLUpdated(String newAvatarURL) {
-		};
-	};
-
-	private static VuzeRelayListener vuzeRelayListener = new VuzeRelayListener() {
-		// @see com.aelitis.azureus.core.messenger.config.VuzeRelayListener#newRelayServerPayLoad(com.aelitis.azureus.buddy.VuzeBuddy, java.lang.String, java.util.Map)
-		public void newRelayServerPayLoad(VuzeBuddy sender, String pkSender,
-				Map decodedMap, long addedOn) {
-			processPayloadMap(pkSender, decodedMap, sender != null, addedOn, true);
-		}
-
-		// @see com.aelitis.azureus.core.messenger.config.VuzeRelayListener#hasPendingRelayMessage(int)
-		public void hasPendingRelayMessage(int count) {
-			if (count == 0) {
-				return;
-			}
-			try {
-				PlatformRelayMessenger.fetch(0);
-				log("have " + count + " pending relay messages. Attempting fetch");
-			} catch (NotLoggedInException e) {
-				log("have " + count + " pending relay messages. Not logged in");
-				// not logged in? oh well, we'd do a fetch on login
-			}
-		}
-	};
-
-
-	private static BuddyPluginListener buddyPluginListener = new BuddyPluginListener() {
-		public void messageLogged(String str, boolean error ) {
-		}
-
-		public void initialised(boolean available) {
-		}
-
-		public void buddyRemoved(BuddyPluginBuddy buddy) {
-			if (!canHandleBuddy(buddy)) {
-				return;
-			}
-			try {
-				buddy_mon.enter();
-
-				String pk = buddy.getPublicKey();
-
-				VuzeBuddy vuzeBuddy = (VuzeBuddy) mapPKtoVuzeBuddy.remove(pk);
-				if (vuzeBuddy != null) {
-					vuzeBuddy.removePublicKey(pk);
-					if (vuzeBuddy.getPublicKeys().length == 0) {
-						try {
-							removeBuddy(vuzeBuddy, true);
-						} catch (NotLoggedInException e) {
-							// should not happen, as we ask user to log in
-							log(e);
-						}
-					}
-				}
-			} finally {
-				buddy_mon.exit();
-			}
-		}
-
-		public void buddyChanged(BuddyPluginBuddy buddy) {
-			if (!canHandleBuddy(buddy)) {
-				return;
-			}
-
-			try {
-				buddy_mon.enter();
-
-				String pk = buddy.getPublicKey();
-
-				VuzeBuddy vuzeBuddy = (VuzeBuddy) mapPKtoVuzeBuddy.get(pk);
-				if (vuzeBuddy != null) {
-					// no need to save.. these are things like YGM marker, buddyactive,
-					// fragment rec'd, closerequest, removeconnection, etc
-					triggerChangeListener(vuzeBuddy, false);
-				} else {
-					buddyAdded(buddy);
-				}
-			} finally {
-				buddy_mon.exit();
-			}
-		}
-
-		public void buddyAdded(BuddyPluginBuddy buddy) {
-			if (!canHandleBuddy(buddy)) {
-				return;
-			}
-
-			buddy.getMessageHandler().addListener(buddy_message_handler_listener);
-		}
-		
-		// @see com.aelitis.azureus.plugins.net.buddy.BuddyPluginListener#enabledStateChanged(boolean)
-		public void enabledStateChanged(boolean enabled) {
-			log("buddy plugin enabled state changed to " + enabled);
-			setupBuddyPlugin();
-			// if we are logged in, fire off a login update trigger, because
-			// it didn't run when we we had the plugin disabled
-			if (LoginInfoManager.getInstance().isLoggedIn()) {
-				loginUpdateTriggered(LoginInfoManager.getInstance().getUserInfo(), true);
-			}
-		}
-	};
-
-	private static BuddyPluginBuddyRequestListener buddyPluginBuddyRequestListener = new BuddyPluginBuddyRequestListener() {
-		public Map requestReceived(BuddyPluginBuddy from_buddy, int subsystem,
-				Map request)
-				throws BuddyPluginException {
-			if (subsystem != BuddyPlugin.SUBSYSTEM_AZ3) {
-				return null;
-			}
-
-			Map mapResponse = new HashMap();
-
-			try {
-				String pk = from_buddy.getPublicKey();
-
-				String reply = processPayloadMap(pk, request,
-						from_buddy.isAuthorised(), SystemTime.getCurrentTime(), true);
-				mapResponse.put("response", reply);
-			} catch (Exception e) {
-				mapResponse.put("response", "Exception: " + e.toString());
-				Debug.out(e);
-			}
-
-			return mapResponse;
-		}
-
-		public void pendingMessages(BuddyPluginBuddy[] from_buddies) {
-			for (int i = 0; i < from_buddies.length; i++) {
-				BuddyPluginBuddy pluginBuddy = from_buddies[i];
-
-				String pk = pluginBuddy.getPublicKey();
-				VuzeBuddy vuzeBuddy = getBuddyByPK(pk);
-				if (vuzeBuddy != null) {
-					log("Relay: YGM from " + pk);
-				} else {
-					log("Relay: YGM from non vuzer " + pk);
-				}
-			}
-			PlatformRelayMessenger.relayCheck();
-		}
-
-	};
-
-	private static boolean pluginEnabled = false;
-
-	private static boolean skipOrderChangedListener;
-
-	
-	/**
-	 * @param vuzeBuddyCreator
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void init(final VuzeBuddyCreator vuzeBuddyCreator) {
-		VuzeBuddyManager.vuzeBuddyCreator = vuzeBuddyCreator;
-
-		PlatformMessenger.setAuthorizedDelayed(true);
-
-		configDir = new File(SystemProperties.getUserPath());
-
-		setupBuddyPlugin();
-	}
-	
-	private static void setupBuddyPlugin() {
-		setSaveDelayed(true);
-
-		try {
-			log("setupBuddyPlugin");
-
-			boolean newPluginEnabled = false;
-
-			try {
-				PluginInterface pi;
-				pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
-						"azbuddy");
-
-				if (pi != null) {
-					Plugin plugin = pi.getPlugin();
-					if (plugin instanceof BuddyPlugin) {
-						((BuddyPlugin) plugin).addListener(buddyPluginListener);
-						if (!pi.getPluginState().isDisabled()) {
-							buddyPlugin = (BuddyPlugin) plugin;
-							newPluginEnabled = buddyPlugin.isEnabled();
-						}
-					}
-				}
-			} catch (Throwable t) {
-				Debug.out(t);
-			}
-
-			if (buddyPlugin == null) {
-				return;
-			}
-
-			if (newPluginEnabled == pluginEnabled) {
-				return;
-			}
-			pluginEnabled = newPluginEnabled;
-
-			if (!pluginEnabled) {
-				buddyPlugin.removeRequestListener(buddyPluginBuddyRequestListener);
-				buddyPlugin = null;
-
-				VuzeCryptoManager.getSingleton().removeListener(vuzeCryptoListener);
-
-				PlatformRelayMessenger.removeRelayServerListener(vuzeRelayListener);
-
-				try {
-					buddy_mon.enter();
-
-					Object[] buddyArray = buddyList.toArray();
-					for (int i = 0; i < buddyArray.length; i++) {
-						VuzeBuddy buddy = (VuzeBuddy) buddyArray[i];
-
-						try {
-							removeBuddy(buddy, false);
-						} catch (NotLoggedInException e) {
-						}
-					}
-
-				} finally {
-					buddy_mon.exit();
-				}
-
-				return;
-			}
-
-			// TODO create an addListener that triggers for existing buddies
-			buddyPlugin.addRequestListener(buddyPluginBuddyRequestListener);
-			List buddies = buddyPlugin.getBuddies();
-			for (int i = 0; i < buddies.size(); i++) {
-				BuddyPluginBuddy buddy = (BuddyPluginBuddy) buddies.get(i);
-				if (canHandleBuddy(buddy)) {
-					buddyPluginListener.buddyAdded(buddy);
-				}
-			}
-
-			VuzeQueuedShares.init(configDir);
-
-			try {
-				loadVuzeBuddies();
-
-				VuzeCryptoManager.getSingleton().addListener(vuzeCryptoListener);
-
-				PlatformRelayMessenger.addRelayServerListener(vuzeRelayListener);
-
-				// do one relay check, which will setup a recheck cycle
-				PlatformRelayMessenger.relayCheck();
-			} catch (Throwable t) {
-				Debug.out(t);
-			}
-
-			LoginInfoManager.getInstance().addListener(loginInfoListener);
-		} finally {
-			setSaveDelayed(false);
-		}
-	}
-
-	/**
-	 * @param info
-	 * @param isNewLoginID
-	 *
-	 * @since 3.0.5.3
-	 */
-	protected static void loginUpdateTriggered(final LoginInfo info,
-			boolean isNewLoginID) {
-		if (!isNewLoginID) {
-			return;
-		}
-
-		// disable buddy communication when plugin is disabled by user
-		if (!pluginEnabled) {
-			// disabled by user or just not enabled yet?
-			boolean inited = COConfigurationManager.getBooleanParameter(
-					"vuze.crypto.manager.initial.login.done", false);
-			if (inited) {
-				// not inited yet, that will happen when we set PW
-				return;
-			}
-		}
-		
-		if (info.userName == null || info.userName.length() == 0) {
-			// not logged in
-			log("Logging out.. clearing password");
-			VuzeCryptoManager.getSingleton().clearPassword();
-
-			PlatformMessenger.setAuthorizedDelayed(true);
-		} else {
-			// logged in
-
-			log("Logging in.. getting pw from webapp");
-
-			// getPassword will set the password via VuzeCryptoManager
-
-			try {
-				// This will run even if DelayAuthorized is true
-				PlatformKeyExchangeMessenger.getPassword(new PlatformKeyExchangeMessenger.platformPasswordListener() {
-					public void passwordRetrieved() {
-						// now password is set we can get access to the public key (or
-						// create one if first time)
-
-						String myPK = null;
-						try {
-							myPK = VuzeCryptoManager.getSingleton().getPublicKey(null);
-						} catch (VuzeCryptoException e) {
-						}
-
-						if (myPK != null && !myPK.equals(info.pk)) {
-							log("webapp's PK (" + info.pk
-									+ ") doesn't match.  Sending out PK");
-							try {
-								// This will run even if DelayAuthorized is true
-								PlatformKeyExchangeMessenger.setPublicKey();
-							} catch (NotLoggedInException e) {
-								log("SPK failed. User must have logged out between getPassword and setPK");
-							}
-						}
-
-						// this will fire off any queued auth messages
-						// TODO: would be nice not to send messages below if they are
-						//       already queued
-						PlatformMessenger.setAuthorizedDelayed(false);
-
-						try {
-							// Don't do relay grab until first sync!
-							PlatformBuddyMessenger.sync(new VuzeBuddySyncListener() {
-								public void syncComplete() {
-									PlatformRelayMessenger.relayCheck();
-								}
-							});
-							PlatformBuddyMessenger.getInvites();
-						} catch (NotLoggedInException e) {
-							PlatformRelayMessenger.relayCheck();
-
-							// this really shouldn't happen unless the user logs in and
-							// out really really fast
-							log("OOPS, sync or getInvite failed because you were no longer logged in");
-						}
-						
-						if (buddyPlugin != null) {
-  						String nickname = buddyPlugin.getNickname();
-  						if (myPK != null
-									&& (nickname == null || nickname.length() == 0)) {
-  							buddyPlugin.setNickname(info.userName + " ("
-  									+ myPK.substring(0, 3) + ")");
-  						}
-						}
-					}
-					
-					// @see com.aelitis.azureus.core.messenger.config.PlatformKeyExchangeMessenger.platformPasswordListener#passwordRetrievalFailed()
-					public void passwordRetrievalFailed() {
-						try {
-							final String url = ContentNetworkUtils.getUrl(
-									ConstantsVuze.getDefaultContentNetwork(),
-									ContentNetwork.SERVICE_LOGOUT);
-							// Authorized Sender has the session cookies the webapp needs
-							// in order to logout.  Use that and ignore the results
-							// We can't just load the logout page into the sidebar's browser,
-							// because that will activate it and confuse the user
-							PlatformAuthorizedSender sender = PlatformMessenger.getAuthorizedTransferListener();
-							AESemaphore sem = new AESemaphore("logoutWait");
-							sender.startDownload(new URL(url), null, sem, false);
-							sem.reserve();
-							// since Authorized Sender doesn't have a BrowserContext,
-							// tell the UI directly that there's no login
-							LoginInfoManager.getInstance().logout();
-						} catch (MalformedURLException e) {
-						}
-					}
-				});
-			} catch (NotLoggedInException e) {
-				// ignore.. we should be logged in!
-				log("calling getPassword RPC afer login failed because we aren't logged in?");
-			}
-		}
-	}
-
-	/**
-	 * Processes a payload map, either from a P2P message, relay server, or
-	 * webapp, or elsewhere.
-	 * 
-	 * @param mapPayload
-	 *s
-	 * @param authorizedBuddy 
-	 * @param addedOn 
-	 * @since 3.0.5.3
-	 */
-	protected static String processPayloadMap(final String pkSender,
-			final Map mapPayload, final boolean authorizedBuddy, final long addedOn,
-			final boolean retryAuthFail) {
-		// TODO: Allow for "try again later" for non auth buddy
-		//       (ie.  A sync up will get the new pk and the message will be valid..)
-
-		String mt = MapUtils.getMapString(mapPayload, VUZE_MESSAGE_TYPE, "");
-
-		log("processing payload " + mt + ";auth=" + authorizedBuddy);
-
-		if (mt.equals(VMT_ACTIVITYENTRY)) {
-			Map mapEntry = (Map) MapUtils.getMapObject(mapPayload, "ActivityEntry",
-					new HashMap(), Map.class);
-			VuzeActivitiesEntry entry = VuzeActivitiesManager.createEntryFromMap(
-					mapEntry, true);
-
-			if (entry != null) {
-				entry.setTimestamp(addedOn);
-				if (authorizedBuddy) {
-					VuzeActivitiesManager.addEntries(new VuzeActivitiesEntry[] {
-						entry
-					});
-					return "Ok";
-				}
-
-				// not Authorized
-				if (VuzeActivitiesConstants.TYPEID_BUDDYREQUEST.equals(entry.getTypeID())) {
-					VuzeActivitiesManager.addEntries(new VuzeActivitiesEntry[] {
-						entry
-					});
-					return "Ok";
-				} else {
-					if (retryAuthFail) {
-						try {
-							PlatformBuddyMessenger.sync(new String[] {
-								pkSender
-							}, new VuzeBuddySyncListener() {
-								public void syncComplete() {
-									processPayloadMap(pkSender, mapPayload, authorizedBuddy,
-											addedOn, false);
-								}
-							});
-						} catch (NotLoggedInException e) {
-							log(e);
-						}
-					} else {
-  					log("Not authorized to add activity " + entry.getID() + ";"
-  							+ entry.getTypeID());
-  					return "Not Authorized";
-					}
-				}
-			}
-		} else if (authorizedBuddy && mt.equals(VMT_BUDDYSYNC)) {
-			try {
-				PlatformBuddyMessenger.sync(null);
-			} catch (NotLoggedInException e) {
-			}
-			return "Ok";
-		} else if (mt.equals(VMT_CHECKINVITES)) {
-			// TODO: Should call getNumPendingInvites once that's hooked up properly
-			//       For now, this will do
-			try {
-				PlatformBuddyMessenger.getInvites();
-			} catch (NotLoggedInException e) {
-			}
-			return "Ok";
-		} else if (mt.equals(VMT_BUDDYACCEPT)) {
-			String code = MapUtils.getMapString(mapPayload, "BuddyAcceptCode", null);
-			VuzeQueuedShares.updateSharePK(code, pkSender);
-
-			VuzeBuddy buddyByPK = getBuddyByPK(pkSender);
-			if (buddyByPK != null) {
-				sendQueudShares(buddyByPK);
-			} else {
-				// Once sync is done, we will get a buddy add, and send the queued share(s)
-				try {
-					PlatformBuddyMessenger.sync(null);
-				} catch (NotLoggedInException e) {
-					log("Not Logged in, yet we were able to decrypt the BuddyAccept message.  Amazing!");
-					log(e);
-				}
-			}
-			return "Ok";
-		} else if (mt.equals(VMT_BUDDY_MESSAGE)) {
-			VuzeBuddy buddyByPK = getBuddyByPK(pkSender);
-			String namespace = MapUtils.getMapString(mapPayload, "namespace", null);
-			Map map = MapUtils.getMapMap(mapPayload, "map", null);
-
-			Object[] listeners = messageListeners.toArray();
-			for (int i = 0; i < listeners.length; i++) {
-				VuzeBuddyMessageListener l = (VuzeBuddyMessageListener) listeners[i];
-				try {
-					l.messageRecieved(buddyByPK, pkSender, namespace, addedOn, map);
-				} catch (Exception e) {
-					log(e);
-				}
-			}
-			return "Ok";
-		}
-
-		log("processPayLoadMap from " + pkSender + ": Unknown Message Type " + mt);
-		return UNKNOWN_MSG_TYPE;
-	}
-
-	/**
-	 * Determines if this is a plugin buddy we should handle in vuze.
-	 * 
-	 * @param buddy
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	private static boolean canHandleBuddy(BuddyPluginBuddy buddy) {
-		if (!isEnabled() || buddy == null) {
-			return false;
-		}
-		if (ALLOW_ONLY_AZ3) {
-			int subsystem = buddy.getSubsystem();
-			return subsystem == BuddyPlugin.SUBSYSTEM_AZ3;
-		}
-
-		return true;
-	}
-
-	/**
-	 * Get direct access tot he buddy plugin.  Usually not a good idea.<br>
-	 * Should be never called from the UI.
-	 * 
-	 * @return MAY BE NULL if plugin not available
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static BuddyPlugin getBuddyPlugin() {
-		return buddyPlugin;
-	}
-	
-	public static boolean
-	canSetPublishedCategory(
-		String		category )
-	{
-		if ( buddyPlugin == null ){
-			
-			return( false );
-		}
-		
-		return( !buddyPlugin.isPublicCategory( category ));
-	}
-	
-	/**
-	 * Retrieve a list of all buddies
-	 * 
-	 * @return List of VuzeBuddy objects.  Adding/Removing from this list
-	 *         does not add/remove buddies
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static List getAllVuzeBuddies() {
-		try {
-			buddy_mon.enter();
-
-			return new ArrayList(buddyList);
-		} finally {
-			buddy_mon.exit();
-		}
-	}
-
-	/**
-	 * Retrieve a VuzeBuddy using their public key
-	 * 
-	 * @param pk
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static VuzeBuddy getBuddyByPK(String pk) {
-		try {
-			buddy_mon.enter();
-
-			return (VuzeBuddy) mapPKtoVuzeBuddy.get(pk);
-		} finally {
-			buddy_mon.exit();
-		}
-	}
-
-	/**
-	 * Retrieve a VuzeBuddy using their login id
-	 * 
-	 * @param loginID
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static VuzeBuddy getBuddyByLoginID(String loginID) {
-		if (loginID == null) {
-			return null;
-		}
-		loginID = loginID.toLowerCase();
-
-		try {
-			buddy_mon.enter();
-
-			// NOTE: Could probably be optimized so we don't search via walk through 
-			for (Iterator iter = buddyList.iterator(); iter.hasNext();) {
-				VuzeBuddy buddy = (VuzeBuddy) iter.next();
-
-				String loginID2 = buddy.getLoginID();
-
-				if (loginID2 != null && loginID.equals(loginID2.toLowerCase())) {
-					return buddy;
-				}
-			}
-		} finally {
-			buddy_mon.exit();
-		}
-		return null;
-	}
-
-	public static void log(String s) {
-		AEDiagnosticsLogger diag_logger = AEDiagnostics.getLogger("v3.Friends");
-		diag_logger.log(s);
-		if (ConstantsVuze.DIAG_TO_STDOUT) {
-			System.out.println(Thread.currentThread().getName() + "|"
-					+ System.currentTimeMillis() + "] " + s);
-		}
-	}
-
-	/**
-	 * @param string
-	 * @param e
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void log(Exception e) {
-		AEDiagnosticsLogger diag_logger = AEDiagnostics.getLogger("v3.Friends");
-		diag_logger.log(e);
-		if (ConstantsVuze.DIAG_TO_STDOUT) {
-			System.err.println(Thread.currentThread().getName() + "|"
-					+ System.currentTimeMillis() + "] ");
-			e.printStackTrace();
-		}
-	}
-
-	/**
-	 * @param buddy
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void addBuddy(VuzeBuddy buddy, boolean createActivityEntry) {
-		try {
-			buddy_mon.enter();
-
-			int index = Collections.binarySearch(buddyList, buddy);
-			if (index < 0) {
-				log("Add new buddy '" + buddy.getDisplayName() + "' to Manager; #pk:"
-						+ buddy.getPublicKeys().length);
-
-				index = -1 * index - 1; // best guess
-
-				buddyList.add(index, buddy);
-
-				if (createActivityEntry) {
-					VuzeActivitiesEntry entry = new VuzeActivitiesEntryBuddyLinkup(buddy);
-					VuzeActivitiesManager.addEntries(new VuzeActivitiesEntry[] {
-						entry
-					});
-				}
-				triggerAddListener(buddy, index);
-
-				saveVuzeBuddies();
-			}
-
-		} finally {
-			buddy_mon.exit();
-		}
-
-		// Send Queued Shares
-		sendQueudShares(buddy);
-		if (createActivityEntry) {
-			removeInviteActivities(buddy.getLoginID());
-		}
-	}
-
-	/**
-	 * Position of the buddy.
-	 * 
-	 * @param buddy
-	 * @return >= 0: position; < 0: Buddy not in list
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static long getBuddyPosition(VuzeBuddy buddy) {
-		try {
-			buddy_mon.enter();
-
-			return Collections.binarySearch(buddyList, buddy);
-		} finally {
-			buddy_mon.exit();
-		}
-	}
-
-	/**
-	 * @param publicKeys
-	 *
-	 * @since 3.0.5.3
-	 */
-	private static void sendQueudShares(VuzeBuddy buddy) {
-		String[] publicKeys = buddy.getPublicKeys();
-		for (int i = 0; i < publicKeys.length; i++) {
-			String pk = publicKeys[i];
-			List shares = VuzeQueuedShares.getSharesByPK(pk);
-			for (Iterator iter = shares.iterator(); iter.hasNext();) {
-				QueuedVuzeShare share = (QueuedVuzeShare) iter.next();
-				VuzeActivitiesEntry entry = share.getActivityEntry();
-				try {
-					buddy.sendActivity(entry);
-					VuzeQueuedShares.remove(share);
-				} catch (NotLoggedInException e) {
-					log("Not logged in: Sending Queued Share");
-				}
-			}
-		}
-	}
-
-	/**
-	 * Creates and adds a new VuzeBuddy via their public key
-	 * 
-	 * @param pk
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static VuzeBuddy createNewBuddy(BuddyPluginBuddy buddy,
-			boolean createActivityEntry) {
-		String pk = buddy.getPublicKey();
-
-		VuzeBuddy newBuddy;
-		if (vuzeBuddyCreator == null) {
-			newBuddy = new VuzeBuddyImpl(pk);
-		} else {
-			newBuddy = vuzeBuddyCreator.createBuddy(pk);
-		}
-
-		if (newBuddy == null) {
-			return null;
-		}
-
-		if (newBuddy != null) {
-			newBuddy.setDisplayName(buddy.getName());
-		}
-
-		getBuddyPluginBuddyForVuze(pk);
-
-		addBuddy(newBuddy, createActivityEntry);
-
-		return newBuddy;
-	}
-
-	public static VuzeBuddy createNewBuddy(Map mapNewBuddy,
-			boolean createActivityEntry) {
-		VuzeBuddy newBuddy = createNewBuddyNoAdd(mapNewBuddy);
-
-		if (newBuddy != null) {
-			addBuddy(newBuddy, createActivityEntry);
-		}
-
-		return newBuddy;
-	}
-
-	/**
-	 * Creates, Adds, and sets properties of a VuzeBuddy using a predefined
-	 * map representation of a VuzeBuddy
-	 * 
-	 * @param mapNewBuddy
-	 * @return 
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static VuzeBuddy createNewBuddyNoAdd(Map mapNewBuddy) {
-		if (buddyPlugin == null) {
-			return null;
-		}
-
-		VuzeBuddy existingBuddy = getBuddyByLoginID(MapUtils.getMapString(
-				mapNewBuddy, "login-id", null));
-		if (existingBuddy != null) {
-			return existingBuddy;
-		}
-
-		VuzeBuddy newBuddy;
-		if (vuzeBuddyCreator == null) {
-			newBuddy = new VuzeBuddyImpl();
-		} else {
-			newBuddy = vuzeBuddyCreator.createBuddy();
-		}
-
-		if (newBuddy == null) {
-			return null;
-		}
-
-		newBuddy.loadFromMap(mapNewBuddy);
-
-		return newBuddy;
-	}
-
-	/**
-	 * @param loginID
-	 * @throws NotLoggedInException 
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void removeBuddy(VuzeBuddy buddy, boolean login)
-			throws NotLoggedInException {
-
-		if (buddy == null) {
-			return;
-		}
-
-		try {
-			buddy_mon.enter();
-
-			if (!buddyList.contains(buddy)) {
-				log("Buddy " + buddy.getDisplayName() + ";" + buddy.getLoginID()
-						+ " already removed via " + Debug.getCompressedStackTrace());
-				return;
-			}
-
-			log("Removing Buddy " + buddy.getDisplayName() + ";" + buddy.getLoginID());
-
-			buddyList.remove(buddy);
-
-			// Would be nice to call buddy.tellBuddyToSyncUp, but since we
-			// are removing the BuddyPluginBuddy almost immediately, we probably
-			// wouldn't get the message out in time.
-			// try {
-			//	buddy.tellBuddyToSyncUp();
-			// } catch (Exception e) {
-			// 	// sync up not super important
-			// }
-
-			String[] publicKeys = buddy.getPublicKeys();
-			for (int i = 0; i < publicKeys.length; i++) {
-				String pk = publicKeys[i];
-
-				buddy.removePublicKey(pk);
-				mapPKtoVuzeBuddy.remove(pk);
-			}
-
-			triggerRemoveListener(buddy);
-		} finally {
-			buddy_mon.exit();
-		}
-
-		if (buddy.getLoginID() != null && buddyPlugin != null) {
-			PlatformBuddyMessenger.remove(buddy, login);
-		}
-	}
-
-	/**
-	 * @param updateTime
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void removeBuddiesOlderThan(long updateTime,
-			boolean tellPlatform) {
-		try {
-			buddy_mon.enter();
-
-			Object[] buddyArray = buddyList.toArray();
-			for (int i = 0; i < buddyArray.length; i++) {
-				VuzeBuddy buddy = (VuzeBuddy) buddyArray[i];
-
-				if (buddy.getLastUpdated() < updateTime) {
-					log("Removing Buddy " + buddy.getDisplayName() + ";"
-							+ buddy.getLoginID() + ";updateTime=" + updateTime + ";buddyTime"
-							+ buddy.getLastUpdated());
-
-					// remove from list first, otherwise removing public keys will
-					// trigger a removeBuddy(VuzeBuddy)
-					buddyList.remove(buddy);
-
-					String[] publicKeys = buddy.getPublicKeys();
-					for (int j = 0; j < publicKeys.length; j++) {
-						String pk = publicKeys[j];
-
-						mapPKtoVuzeBuddy.remove(pk);
-						buddy.removePublicKey(pk);
-					}
-
-					triggerRemoveListener(buddy);
-
-					if (tellPlatform && buddy.getLoginID() != null) {
-						try {
-							PlatformBuddyMessenger.remove(buddy, false);
-						} catch (NotLoggedInException e) {
-							// ignore.. we should be logged in since this is called via
-							// sync.  If we aren't, it doesn't matter too much, we'll
-							// remove them next sync
-						}
-					}
-				}
-			}
-
-			saveVuzeBuddies();
-
-		} finally {
-			buddy_mon.exit();
-		}
-	}
-
-	/**
-	 * @param pk
-	 * @param vuzeBuddyImpl
-	 *
-	 * @since 3.0.5.3
-	 */
-	protected static void linkPKtoBuddy(String pk, VuzeBuddy buddy) {
-		try {
-			buddy_mon.enter();
-
-			VuzeBuddy existingBuddy = (VuzeBuddy) mapPKtoVuzeBuddy.get(pk);
-
-			if (existingBuddy != null) {
-				if (!existingBuddy.getLoginID().equalsIgnoreCase(buddy.getLoginID())) {
-					log("DANGER: Changing PK's user from " + existingBuddy.getLoginID()
-							+ " to " + buddy.getLoginID());
-					mapPKtoVuzeBuddy.put(pk, buddy);
-				}
-			} else {
-				log("add PK " + pk + " to " + buddy.getLoginID());
-				mapPKtoVuzeBuddy.put(pk, buddy);
-			}
-
-		} finally {
-			buddy_mon.exit();
-		}
-	}
-
-	/**
-	 * Gets a BuddyPluginBuddy using a public key.  Creates the BuddyPluginBuddy
-	 * if it doesn't exist yet.  Ensures it's of Vuze type.
-	 * 
-	 * @param pk
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	protected static BuddyPluginBuddy getBuddyPluginBuddyForVuze(String pk) {
-		if (buddyPlugin == null) {
-			return null;
-		}
-		
-		return( buddyPlugin.addBuddy(pk, BuddyPlugin.SUBSYSTEM_AZ3));
-	}
-
-	private static void invitePKs(String[] pks, String code) {
-		if (buddyPlugin == null) {
-			return;
-		}
-
-		if (pks != null && pks.length > 0) {
-			final BuddyPluginBuddy[] pluginBuddies = new BuddyPluginBuddy[pks.length];
-			for (int i = 0; i < pks.length; i++) {
-				String pk = pks[i];
-
-				pluginBuddies[i] = buddyPlugin.addBuddy(pk, BuddyPlugin.SUBSYSTEM_AZ3);
-			}
-
-			// Webapp will store invite info for User B.  We just need to tell them
-			// to sync up if we can
-
-			// Wait 10 seconds after adding a buddy as we might find out they are online
-			// within that time (and be able to send the message directly)
-			SimpleTimer.addEvent("send invites", SystemTime.getOffsetTime(10000),
-					new TimerEventPerformer() {
-						public void perform(TimerEvent event) {
-							Map map = new HashMap();
-							map.put(VUZE_MESSAGE_TYPE, VMT_CHECKINVITES);
-
-							try {
-								sendPayloadMap(map, pluginBuddies);
-							} catch (NotLoggedInException e) {
-								log(e);
-							}
-						}
-					});
-		}
-	}
-
-	/**
-	 * 
-	 * @param invites This is the map that comes from the webpage after it
-	 *                sends outs the invites
-	 * @param contentToShare the content you wish to share (null if none)
-	 * @param shareMessage The message the user typed to go with the share
-	 * @param buddies The buddies that should be notified (null ok)
-	 * @throws NotLoggedInException 
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void inviteWithShare(final Map invites,
-			final VuzeShareable contentToShare, final String shareMessage,
-			final VuzeBuddy[] buddies)
-			throws NotLoggedInException {
-		if (!LoginInfoManager.getInstance().isLoggedIn()) {
-			throw new NotLoggedInException();
-		}
-		new AEThread2("inviteWithShare", true) {
-			public void run() {
-				try {
-					_inviteWithShare(invites, contentToShare, shareMessage, buddies);
-				} catch (NotLoggedInException e) {
-					Debug.out(e);
-				}
-			}
-		}.start();
-	}
-
-	private static void _inviteWithShare(Map invites,
-			VuzeShareable contentToShare, String shareMessage,
-			VuzeBuddy[] buddies)
-			throws NotLoggedInException {
-
-		if (!LoginInfoManager.getInstance().isLoggedIn()) {
-			throw new NotLoggedInException();
-		}
-
-		String name = "na";
-		if (contentToShare != null) {
-			
-			DownloadManager dm = contentToShare.getDownloadManager();
-			
-			name = dm == null ? contentToShare.getDisplayName()
-					: dm.toString();
-		}
-
-		if (buddies != null && contentToShare != null) {
-			log("share " + name + " with " + buddies.length + " existing buddies");
-			for (int i = 0; i < buddies.length; i++) {
-				VuzeBuddy v3Buddy = buddies[i];
-				if (v3Buddy != null) {
-					v3Buddy.shareDownload(contentToShare, shareMessage);
-				}
-			}
-		}
-
-		Map inviteMessage = MapUtils.getMapMap(invites, "message", null);
-		if (inviteMessage == null) {
-			inviteMessage = invites;
-		}
-		List sentInvitations = MapUtils.getMapList(inviteMessage, "sentInvitations",
-				Collections.EMPTY_LIST);
-
-		log("invite " + sentInvitations.size() + " ppl, sharing " + name);
-
-		List displayNames = new ArrayList();
-		for (Iterator iter = sentInvitations.iterator(); iter.hasNext();) {
-			Map mapInvitation = (Map) iter.next();
-
-			boolean success = MapUtils.getMapBoolean(mapInvitation, "success", false);
-			if (success) {
-				String code = MapUtils.getMapString(mapInvitation, "code", null);
-
-				if (contentToShare != null) {
-					queueShare(contentToShare, shareMessage, code);
-				}
-
-				List pkList = MapUtils.getMapList(mapInvitation, "pks",
-						Collections.EMPTY_LIST);
-				String[] newPKs = (String[]) pkList.toArray(new String[0]);
-
-				VuzeBuddyManager.invitePKs(newPKs, code);
-				String[] nameArray = {
-					MapUtils.getMapString(mapInvitation, "value", "???"),
-					MapUtils.getMapString(mapInvitation, "display-name", null)
-				};
-				displayNames.add(nameArray);
-			}
-		}
-		if (displayNames.size() > 0) {
-			VuzeActivitiesBuddyInvited entry = new VuzeActivitiesBuddyInvited(displayNames);
-			VuzeActivitiesManager.addEntries(new VuzeActivitiesEntry[] {
-				entry
-			});
-		}
-	}
-
-	private static void queueShare(VuzeShareable content, String message,
-			String code) {
-		if (content == null) {
-			return;
-		}
-
-		VuzeActivitiesEntry entry;
-		try {
-			entry = new VuzeActivitiesEntryContentShare(content, message);
-
-			QueuedVuzeShare vuzeShare = VuzeQueuedShares.add(code);
-			vuzeShare.setDownloadHash(entry.getAssetHash());
-			vuzeShare.setActivityEntry(entry);
-			VuzeQueuedShares.save();
-		} catch (NotLoggedInException e) {
-			Debug.out(e);
-		}
-	}
-
-	public static void removeInviteActivities(String fromLoginID) {
-		if (fromLoginID == null) {
-			return;
-		}
-		List requestEntries = new ArrayList();
-		VuzeActivitiesEntry[] allEntries = VuzeActivitiesManager.getAllEntries();
-		for (int i = 0; i < allEntries.length; i++) {
-			VuzeActivitiesEntry entry = allEntries[i];
-			if (entry instanceof VuzeActivitiesEntryBuddyRequest) {
-				VuzeActivitiesEntryBuddyRequest inviteEntry = (VuzeActivitiesEntryBuddyRequest) entry;
-				if (fromLoginID.equals(inviteEntry.getBuddy().getLoginID())) {
-					requestEntries.add(entry);
-				}
-			}
-		}
-		if (requestEntries.size() > 0) {
-			VuzeActivitiesEntry[] toRemove = (VuzeActivitiesEntry[]) requestEntries.toArray(new VuzeActivitiesEntry[requestEntries.size()]);
-			VuzeActivitiesManager.removeEntries(toRemove);
-		}
-	}
-
-	/**
-	 * You've accepted an invite
-	 * 
-	 * @param code Invite code or somesuch id that the webapp gave you
-	 * @param pks Public Keys of the user you accepted the invite from
-	 * @throws NotLoggedInException 
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void acceptInvite(final String code, final String pks[])
-			throws NotLoggedInException {
-		if (!isEnabled()) {
-			showDisabledDialog();
-			return;
-		}
-		// sync will get new buddy connection
-		PlatformBuddyMessenger.sync(new VuzeBuddySyncListener() {
-			public void syncComplete() {
-				log("Sending Invite Accept; code=" + code);
-				Map map = new HashMap();
-				map.put(VUZE_MESSAGE_TYPE, VMT_BUDDYACCEPT);
-				map.put("BuddyAcceptCode", code);
-
-				for (int i = 0; i < pks.length; i++) {
-					String pk = pks[i];
-
-					VuzeBuddy buddy = getBuddyByPK(pk);
-
-					if (buddy != null) {
-						try {
-							buddy.sendPayloadMap(map);
-						} catch (NotLoggedInException e) {
-							log("Not Logged In: Accept Invite");
-						}
-						// send will send to all public keys of buddy, so there's no need
-						// to go through the rest of the pks
-						break;
-					}
-				}
-			}
-		});
-	}
-
-	protected static void sendActivity(VuzeActivitiesEntry entry,
-			BuddyPluginBuddy[] buddies)
-			throws NotLoggedInException {
-		final Map map = new HashMap();
-
-		map.put(VUZE_MESSAGE_TYPE, VMT_ACTIVITYENTRY);
-		map.put("ActivityEntry", entry.toMap());
-
-		sendPayloadMap(map, buddies);
-	}
-
-	/**
-	 * @param map
-	 * @param buddies
-	 * @throws NotLoggedInException 
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void sendPayloadMap(final Map map, BuddyPluginBuddy[] buddies)
-			throws NotLoggedInException {
-		if (buddyPlugin == null) {
-			return;
-		}
-		if (!LoginInfoManager.getInstance().isLoggedIn()) {
-			throw new NotLoggedInException();
-		}
-		try {
-			log("sending map to " + buddies.length + " PKs");
-			for (int i = 0; i < buddies.length; i++) {
-				BuddyPluginBuddy pluginBuddy = buddies[i];
-
-				// outcome reported via buddy's message handler listener
-				pluginBuddy.getMessageHandler().queueMessage(BuddyPlugin.SUBSYSTEM_AZ3,
-						map, SEND_P2P_TIMEOUT);
-			}
-		} catch (BuddyPluginException e) {
-			log(e);
-		}
-	}
-
-	public static void addListener(VuzeBuddyListener l, boolean trigger) {
-		if (!listeners.contains(l)) {
-			listeners.add(l);
-		}
-		if (trigger) {
-			Object[] buddies = buddyList.toArray();
-			for (int i = 0; i < buddies.length; i++) {
-				VuzeBuddy buddy = (VuzeBuddy) buddies[i];
-				l.buddyAdded(buddy, i);
-			}
-		}
-	}
-
-	public static void removeListener(VuzeBuddyListener l) {
-		listeners.remove(l);
-	}
-
-	/**
-	 * @param buddy
-	 *
-	 * @since 3.0.5.3
-	 */
-	private static void triggerRemoveListener(VuzeBuddy buddy) {
-		Object[] listenersArray = listeners.toArray();
-		for (int i = 0; i < listenersArray.length; i++) {
-			VuzeBuddyListener l = (VuzeBuddyListener) listenersArray[i];
-			l.buddyRemoved(buddy);
-		}
-		
-		VuzeBuddyListener[] buddyListeners = buddy.getListeners();
-		for (int i = 0; i < buddyListeners.length; i++) {
-			VuzeBuddyListener l = buddyListeners[i];
-			l.buddyRemoved(buddy);
-		}
-	}
-
-	/**
-	 * @param buddy
-	 *
-	 * @since 3.0.5.3
-	 */
-	private static void triggerAddListener(VuzeBuddy buddy, int position) {
-		Object[] listenersArray = listeners.toArray();
-		for (int i = 0; i < listenersArray.length; i++) {
-			VuzeBuddyListener l = (VuzeBuddyListener) listenersArray[i];
-			l.buddyAdded(buddy, position);
-		}
-
-		VuzeBuddyListener[] buddyListeners = buddy.getListeners();
-		for (int i = 0; i < buddyListeners.length; i++) {
-			VuzeBuddyListener l = buddyListeners[i];
-			l.buddyAdded(buddy, position);
-		}
-	}
-
-	protected static void triggerChangeListener(VuzeBuddy buddy) {
-		triggerChangeListener(buddy, false);
-	}
-
-	/**
-	 * @param buddy
-	 *
-	 * @since 3.0.5.3
-	 */
-	protected static void triggerChangeListener(VuzeBuddy buddy, boolean save) {
-		if (!buddyList.contains(buddy)) {
-			return;
-		}
-
-		if (save) {
-			saveVuzeBuddies();
-		}
-		Object[] listenersArray = listeners.toArray();
-		for (int i = 0; i < listenersArray.length; i++) {
-			VuzeBuddyListener l = (VuzeBuddyListener) listenersArray[i];
-			l.buddyChanged(buddy);
-		}
-
-		VuzeBuddyListener[] buddyListeners = buddy.getListeners();
-		for (int i = 0; i < buddyListeners.length; i++) {
-			VuzeBuddyListener l = buddyListeners[i];
-			l.buddyChanged(buddy);
-		}
-	}
-
-	protected static void triggerOrderChangedListener() {
-		if (skipOrderChangedListener) {
-			return;
-		}
-		Collections.sort(buddyList);
-		Object[] listenersArray = listeners.toArray();
-		for (int i = 0; i < listenersArray.length; i++) {
-			VuzeBuddyListener l = (VuzeBuddyListener) listenersArray[i];
-			l.buddyOrderChanged();
-		}
-	}
-
-	private static void saveVuzeBuddies() {
-		if (isSaveDelayed()) {
-			return;
-		}
-
-		log("save " + Debug.getCompressedStackTrace());
-		Map mapSave = new HashMap();
-		List storedBuddyList = new ArrayList();
-		mapSave.put("buddies", storedBuddyList);
-
-		try {
-			buddy_mon.enter();
-
-			for (Iterator iter = buddyList.iterator(); iter.hasNext();) {
-				VuzeBuddy buddy = (VuzeBuddy) iter.next();
-
-				if (buddy != null) {
-					storedBuddyList.add(buddy.toMap());
-				}
-			}
-
-			FileUtil.writeResilientFile(configDir, SAVE_FILENAME, mapSave, true);
-		} finally {
-			buddy_mon.exit();
-		}
-	}
-
-	private static void loadVuzeBuddies() {
-		Map map = FileUtil.readResilientFile(configDir, SAVE_FILENAME, true);
-		
-		skipOrderChangedListener = true;
-
-		List storedBuddyList = MapUtils.getMapList(map, "buddies",
-				Collections.EMPTY_LIST);
-
-		for (Iterator iter = storedBuddyList.iterator(); iter.hasNext();) {
-			Map mapBuddy = (Map) iter.next();
-
-			createNewBuddy(mapBuddy, false);
-		}
-		
-		skipOrderChangedListener = false;
-
-		// this will resort
-		triggerOrderChangedListener();
-	}
-
-	/**
-	 * Create a Buddy object but without a true relationship to the user.
-	 * 
-	 * @param mapBuddy
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static VuzeBuddy createPotentialBuddy(Map mapBuddy) {
-		VuzeBuddy newBuddy;
-		if (vuzeBuddyCreator == null) {
-			newBuddy = new VuzeBuddyFakeImpl(mapBuddy);
-		} else {
-			newBuddy = vuzeBuddyCreator.createPotentialBuddy(mapBuddy);
-		}
-		return newBuddy;
-	}
-
-	/**
-	 * @param mapBuddy
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static VuzeBuddy getOrCreatePotentialBuddy(Map mapBuddy) {
-		String loginID = MapUtils.getMapString(mapBuddy, "login-id", null);
-		if (loginID != null) {
-			VuzeBuddy vuzeBuddy = getBuddyByLoginID(loginID);
-			if (vuzeBuddy != null) {
-				return vuzeBuddy;
-			}
-		}
-		return createPotentialBuddy(mapBuddy);
-	}
-
-	/**
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static boolean isEnabled() {
-		return pluginEnabled;
-	}
-	
-	public static void showDisabledDialog() {
-		UIFunctions uif = UIFunctionsManager.getUIFunctions();
-		if (uif != null) {
-			uif.promptUser(MessageText.getString("v3.buddies.disabled.title"),
-					MessageText.getString("v3.buddies.disabled.text"), new String[] {
-						MessageText.getString("Button.ok")
-					}, 0, null, null, false, 0);
-		}
-	}
-
-	/**
-	 * @param saveDelayed the saveDelayed to set
-	 */
-	public static void setSaveDelayed(boolean saveDelayed) {
-		if (VuzeBuddyManager.saveDelayed != saveDelayed) {
-			VuzeBuddyManager.saveDelayed = saveDelayed;
-			if (!saveDelayed) {
-				saveVuzeBuddies();
-			}
-		}
-	}
-
-	/**
-	 * @return the saveDelayed
-	 */
-	public static boolean isSaveDelayed() {
-		return saveDelayed;
-	}
-	
-	public static String generateBuddyAHREF(String loginID, String displayName,
-			String referer) {
-		StringBuffer buf = new StringBuffer();
-
-		buf.append("<A HREF=\"");
-		buf.append(ConstantsVuze.getDefaultContentNetwork().getProfileService(loginID,referer));
-		buf.append("\" TITLE=\"");
-		buf.append(displayName);
-		if (!loginID.equals(displayName)) {
-			buf.append(" (");
-			buf.append(loginID);
-			buf.append(")");
-		}
-		buf.append("\">");
-		buf.append(displayName);
-		buf.append("</A>");
-		return buf.toString();
-	}
-	
-	public static void addMessageListener(VuzeBuddyMessageListener l) {
-		if (!messageListeners.contains(l)) {
-			messageListeners.add(l);
-		}
-	}
-
-	public static void removeMessageListener(VuzeBuddyMessageListener l) {
-		messageListeners.remove(l);
-	}
-}
diff --git a/com/aelitis/azureus/buddy/impl/VuzeBuddyMessageListener.java b/com/aelitis/azureus/buddy/impl/VuzeBuddyMessageListener.java
deleted file mode 100644
index 2d0a71f..0000000
--- a/com/aelitis/azureus/buddy/impl/VuzeBuddyMessageListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Created on Jun 25, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
- 
-package com.aelitis.azureus.buddy.impl;
-
-import java.util.Map;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-
-/**
- * @author TuxPaper
- * @created Jun 25, 2008
- *
- */
-public interface VuzeBuddyMessageListener
-{
-	public void 
-	messageRecieved(
-		VuzeBuddy 			buddy, 
-		String 				originatorPK, 
-		String 				namespace,
-		long				sent_at,
-		Map 				message);
-}
diff --git a/com/aelitis/azureus/buddy/impl/VuzeQueuedShares.java b/com/aelitis/azureus/buddy/impl/VuzeQueuedShares.java
deleted file mode 100644
index d06ebf0..0000000
--- a/com/aelitis/azureus/buddy/impl/VuzeQueuedShares.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/**
- * Created on Apr 22, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.buddy.impl;
-
-import java.io.File;
-import java.util.*;
-
-import org.gudy.azureus2.core3.util.*;
-
-import com.aelitis.azureus.buddy.QueuedVuzeShare;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author TuxPaper
- * @created Apr 22, 2008
- *
- */
-public class VuzeQueuedShares
-{
-	private static final long EXPIREY_MS = 1000l * 60 * 60 * 24 * 30;
-
-	private static List shares = new ArrayList();
-
-	private static AEMonitor shares_mon = new AEMonitor("Qd Shares");
-
-	private static String SAVE_FILENAME = "v3.QdShares.dat";
-
-	private static File configDir;
-
-	/**
-	 * @param code
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static List getSharesByCode(String code) {
-		List results = new ArrayList();
-
-		shares_mon.enter();
-		try {
-			for (Iterator iter = shares.iterator(); iter.hasNext();) {
-				QueuedVuzeShare share = (QueuedVuzeShare) iter.next();
-
-				if (share.getCode().equals(code)) {
-					results.add(share);
-				}
-			}
-		} finally {
-			shares_mon.exit();
-		}
-		return results;
-	}
-
-	/**
-	 * @param pkSender
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void updateSharePK(String code, String pkSender) {
-		List sharesByCode = VuzeQueuedShares.getSharesByCode(code);
-
-		log("Updating " + sharesByCode.size() + " shares with code " + code
-				+ " to pk " + pkSender);
-
-		for (Iterator iter = sharesByCode.iterator(); iter.hasNext();) {
-			QueuedVuzeShare share = (QueuedVuzeShare) iter.next();
-
-			share.setPk(pkSender);
-		}
-		save();
-	}
-
-	/**
-	 * @param pk
-	 * @return 
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static List getSharesByPK(String pk) {
-		List results = new ArrayList();
-		
-		if (pk == null) {
-			return results;
-		}
-
-		shares_mon.enter();
-		try {
-			for (Iterator iter = shares.iterator(); iter.hasNext();) {
-				QueuedVuzeShare share = (QueuedVuzeShare) iter.next();
-
-				if (pk.equals(share.getPk())) {
-					results.add(share);
-				}
-			}
-		} finally {
-			shares_mon.exit();
-		}
-		return results;
-	}
-
-	/**
-	 * @param share
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void remove(QueuedVuzeShare share) {
-		shares_mon.enter();
-		try {
-			shares.remove(share);
-		} finally {
-			shares_mon.exit();
-		}
-		log("Remove");
-	}
-
-	/**
-	 * @param code
-	 * @return 
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static QueuedVuzeShare add(String code) {
-		QueuedVuzeShare share = new QueuedVuzeShare();
-		share.setCode(code);
-
-		shares_mon.enter();
-		try {
-			shares.add(share);
-		} finally {
-			shares_mon.exit();
-		}
-
-		log("Share Added for code " + code);
-		return share;
-	}
-
-	public static void save() {
-		log("Qd Shares Save");
-
-		Map mapSave = new HashMap();
-		List storedShareList = new ArrayList();
-		mapSave.put("shares", storedShareList);
-
-		try {
-			shares_mon.enter();
-
-			for (Iterator iter = shares.iterator(); iter.hasNext();) {
-				QueuedVuzeShare share = (QueuedVuzeShare) iter.next();
-
-				if (share != null) {
-					storedShareList.add(share.toMap());
-				}
-			}
-
-			FileUtil.writeResilientFile(configDir, SAVE_FILENAME, mapSave, true);
-		} finally {
-			shares_mon.exit();
-		}
-	}
-
-	private static void load() {
-		Map map = FileUtil.readResilientFile(configDir, SAVE_FILENAME, true);
-
-		List storedBuddyList = MapUtils.getMapList(map, "shares",
-				Collections.EMPTY_LIST);
-
-		shares_mon.enter();
-		try {
-			shares.clear();
-
-			long tooOld = SystemTime.getCurrentTime() - EXPIREY_MS;
-			
-			for (Iterator iter = storedBuddyList.iterator(); iter.hasNext();) {
-				Map mapBuddy = (Map) iter.next();
-
-				QueuedVuzeShare share = new QueuedVuzeShare(mapBuddy);
-				
-				if (share.getSharedOn() > tooOld) {
-					shares.add(share);
-				}
-			}
-		} finally {
-			shares_mon.exit();
-		}
-
-		log("Qd Shares Load.  Size=" + shares.size());
-	}
-
-	/**
-	 * 
-	 *
-	 * @param configDir 
-	 * @since 3.0.5.3
-	 */
-	public static void init(File configDir) {
-		VuzeQueuedShares.configDir = configDir;
-		try {
-			load();
-		} catch (Exception e) {
-			Debug.out(e);
-		}
-	}
-
-	private static void log(String s) {
-		VuzeBuddyManager.log("[Qd Shares] " + s);
-	}
-}
diff --git a/com/aelitis/azureus/core/cnetwork/ContentNetwork.java b/com/aelitis/azureus/core/cnetwork/ContentNetwork.java
index 5f7c7c0..f830c46 100644
--- a/com/aelitis/azureus/core/cnetwork/ContentNetwork.java
+++ b/com/aelitis/azureus/core/cnetwork/ContentNetwork.java
@@ -37,6 +37,8 @@ ContentNetwork
 	
 	public static final long	CONTENT_NETWORK_RFN			= 2;
 	
+	public static final long	CONTENT_NETWORK_VHDNL		= 3;
+
 		// test networks
 	
 	public static final long	CONTENT_NETWORK_JR			= 10000;
diff --git a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuze.java b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuze.java
index 337bde0..a5fe6e8 100644
--- a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuze.java
+++ b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuze.java
@@ -28,7 +28,7 @@ public class
 ContentNetworkVuze 
 	extends ContentNetworkVuzeGeneric
 {
-	private static final String DEFAULT_ADDRESS = "www.vuze.com"; //DO NOT TOUCH !!!!  use the -Dplatform_address=ip override instead
+	private static final String DEFAULT_ADDRESS = "client.vuze.com"; //DO NOT TOUCH !!!!  use the -Dplatform_address=ip override instead
 
 	private static final String DEFAULT_PORT = "80";
 
diff --git a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuzeGeneric.java b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuzeGeneric.java
index 94a213e..89d104d 100644
--- a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuzeGeneric.java
+++ b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuzeGeneric.java
@@ -1,6 +1,6 @@
 /*
- * Created on Nov 25, 2008
  * Created by Paul Gardner
+ * Created on Nov 25, 2008
  * 
  * Copyright 2008 Vuze, Inc.  All rights reserved.
  * 
@@ -54,7 +54,8 @@ ContentNetworkVuzeGeneric
 					
 					URL_SUFFIX = 	"azid=" 	+ Base32.encode(VuzeCryptoManager.getSingleton().getPlatformAZID()) +
 									"&azv=" 	+ Constants.AZUREUS_VERSION +
-									"&locale=" 	+ Locale.getDefault().toString();
+									"&locale=" 	+ Locale.getDefault().toString() +
+									"&os.name=" + UrlUtils.encode(System.getProperty("os.name"));
 					String suffix = System.getProperty("url.suffix", null);
 					if (suffix != null) {
 						URL_SUFFIX += "&" + suffix;
@@ -194,8 +195,8 @@ ContentNetworkVuzeGeneric
 		service_map.clear();
 		
 		addService( SERVICE_SEARCH, 			URL_PREFIX + "search?q=" );
-		addService( SERVICE_XSEARCH, 			URL_PREFIX + "xsearch?q=" );
-		addService( SERVICE_RPC, 				URL_PREFIX + "rpc/" );
+		addService( SERVICE_XSEARCH, 			URL_PREFIX + "xsearch/index.php?q=" );
+		addService( SERVICE_RPC, 				"http://vrpc.vuze.com/vzrpc/rpc.php" );
 		addService( SERVICE_BIG_BROWSE, 		URL_PREFIX + "browse.start?" );
 		addService( SERVICE_PUBLISH, 			URL_PREFIX + "publish.start?" );
 		addService( SERVICE_WELCOME, 			URL_PREFIX + "welcome.start?" );
@@ -215,7 +216,7 @@ ContentNetworkVuzeGeneric
 		addService( SERVICE_MY_ACCOUNT,			URL_PREFIX + "account.start?" );
 		addService( SERVICE_SITE_RELATIVE,		URL_PREFIX );
 		addService( SERVICE_ADD_FRIEND,			URL_PREFIX + "user/AddFriend.html?" );
-		addService( SERVICE_SUBSCRIPTION,		URL_PREFIX + "xsearch?" );
+		addService( SERVICE_SUBSCRIPTION,		URL_PREFIX + "xsearch/index.php?" );
 		 		
 		addService( SERVICE_AUTHORIZE,			URL_PREFIX + "ip.start?" );
 		addService( SERVICE_GET_ICON,			URL_ICON );
diff --git a/com/aelitis/azureus/core/content/RelatedContent.java b/com/aelitis/azureus/core/content/RelatedContent.java
index 474c484..a751c6c 100644
--- a/com/aelitis/azureus/core/content/RelatedContent.java
+++ b/com/aelitis/azureus/core/content/RelatedContent.java
@@ -24,6 +24,8 @@ package com.aelitis.azureus.core.content;
 import org.gudy.azureus2.core3.util.Base32;
 import org.gudy.azureus2.plugins.download.Download;
 
+import com.aelitis.azureus.core.cnetwork.ContentNetwork;
+
 public abstract class 
 RelatedContent 
 {
@@ -31,6 +33,9 @@ RelatedContent
 	final private byte[]		hash;
 	final private String		tracker;
 	final private long			size;
+	private int					date;
+	private int					seeds_leechers;
+	private byte				content_network;
 	
 	private byte[]		related_to_hash;
 
@@ -40,13 +45,19 @@ RelatedContent
 		String		_title,
 		byte[]		_hash,
 		String		_tracker,
-		long		_size )
+		long		_size,
+		int			_date,
+		int			_seeds_leechers,
+		byte		_cnet )
 	{
 		related_to_hash		= _related_to_hash;
 		title				= _title;
 		hash				= _hash;
 		tracker				= _tracker;
 		size				= _size;
+		date				= _date;
+		seeds_leechers		= _seeds_leechers;
+		content_network		= _cnet;
 	}
 	
 	protected
@@ -54,12 +65,18 @@ RelatedContent
 		String		_title,
 		byte[]		_hash,
 		String		_tracker,
-		long		_size )
+		long		_size,
+		int			_date,
+		int			_seeds_leechers,
+		byte		_cnet )
 	{
-		title		= _title;
-		hash		= _hash;
-		tracker		= _tracker;
-		size		= _size;
+		title				= _title;
+		hash				= _hash;
+		tracker				= _tracker;
+		size				= _size;
+		date				= _date;
+		seeds_leechers		= _seeds_leechers;
+		content_network		= _cnet;
 	}
 	
 	protected void
@@ -118,12 +135,79 @@ RelatedContent
 		return( size );
 	}
 	
+	public long
+	getPublishDate()
+	{
+		return( date*60*60*1000L );
+	}
+	
+	protected int
+	getDateHours()
+	{
+		return( date );
+	}
+	
+	protected void
+	setDateHours(
+		int		_date )
+	{
+		date = _date;
+	}
+	
+	public int
+	getLeechers()
+	{
+		if ( seeds_leechers == -1 ){
+			
+			return( -1 );
+		}
+		
+		return( seeds_leechers&0xffff );
+	}
+	
+	public int
+	getSeeds()
+	{
+		if ( seeds_leechers == -1 ){
+			
+			return( -1 );
+		}
+		
+		return( (seeds_leechers>>16) & 0xffff );
+	}
+	
+	protected int
+	getSeedsLeechers()
+	{
+		return( seeds_leechers );
+	}
+	
+	protected void
+	setSeedsLeechers(
+		int		_sl )
+	{
+		seeds_leechers = _sl;
+	}
+	
+	public long
+	getContentNetwork()
+	{
+		return((content_network&0xff)==0xff?ContentNetwork.CONTENT_NETWORK_UNKNOWN:(content_network&0xff));
+	}
+	
+	protected void
+	setContentNetwork(
+		long		cnet )
+	{
+		content_network = (byte)cnet;
+	}
+	
 	public abstract void
 	delete();
 	
 	public String
 	getString()
 	{
-		return( "title=" + title + ", hash=" + (hash==null?"null":Base32.encode( hash )) + ", tracker=" + tracker );
+		return( "title=" + title + ", hash=" + (hash==null?"null":Base32.encode( hash )) + ", tracker=" + tracker +", date=" + date + ", sl=" + seeds_leechers + ", cnet=" + content_network );
 	}
 }
diff --git a/com/aelitis/azureus/core/content/RelatedContentManager.java b/com/aelitis/azureus/core/content/RelatedContentManager.java
index 9aa79be..841b9d5 100644
--- a/com/aelitis/azureus/core/content/RelatedContentManager.java
+++ b/com/aelitis/azureus/core/content/RelatedContentManager.java
@@ -21,21 +21,30 @@
 
 package com.aelitis.azureus.core.content;
 
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
 import java.lang.ref.WeakReference;
+import java.net.InetSocketAddress;
+import java.net.URL;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Pattern;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.download.DownloadManagerState;
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.AESemaphore;
+import org.gudy.azureus2.core3.util.AEThread2;
 import org.gudy.azureus2.core3.util.AsyncDispatcher;
 import org.gudy.azureus2.core3.util.BDecoder;
 import org.gudy.azureus2.core3.util.BEncoder;
 import org.gudy.azureus2.core3.util.Base32;
 import org.gudy.azureus2.core3.util.ByteArrayHashMap;
 import org.gudy.azureus2.core3.util.ByteFormatter;
+import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.FileUtil;
 import org.gudy.azureus2.core3.util.RandomUtils;
@@ -48,14 +57,32 @@ import org.gudy.azureus2.core3.util.TimerEventPerformer;
 import org.gudy.azureus2.core3.util.TorrentUtils;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.PluginListener;
+import org.gudy.azureus2.plugins.ddb.DistributedDatabase;
+import org.gudy.azureus2.plugins.ddb.DistributedDatabaseContact;
+import org.gudy.azureus2.plugins.ddb.DistributedDatabaseException;
+import org.gudy.azureus2.plugins.ddb.DistributedDatabaseKey;
+import org.gudy.azureus2.plugins.ddb.DistributedDatabaseProgressListener;
+import org.gudy.azureus2.plugins.ddb.DistributedDatabaseTransferHandler;
+import org.gudy.azureus2.plugins.ddb.DistributedDatabaseTransferType;
+import org.gudy.azureus2.plugins.ddb.DistributedDatabaseValue;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.download.DownloadManager;
 import org.gudy.azureus2.plugins.download.DownloadManagerListener;
 import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
+import org.gudy.azureus2.plugins.utils.search.SearchException;
+import org.gudy.azureus2.plugins.utils.search.SearchInstance;
+import org.gudy.azureus2.plugins.utils.search.SearchObserver;
+import org.gudy.azureus2.plugins.utils.search.SearchProvider;
+import org.gudy.azureus2.plugins.utils.search.SearchResult;
 import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 
 import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.cnetwork.ContentNetwork;
+import com.aelitis.azureus.core.dht.DHT;
+import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
+import com.aelitis.azureus.core.dht.transport.udp.DHTTransportUDP;
+import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.core.util.FeatureAvailability;
 import com.aelitis.azureus.core.util.bloom.BloomFilter;
@@ -65,15 +92,23 @@ import com.aelitis.azureus.plugins.dht.DHTPluginContact;
 import com.aelitis.azureus.plugins.dht.DHTPluginOperationListener;
 import com.aelitis.azureus.plugins.dht.DHTPluginValue;
 import com.aelitis.azureus.util.ImportExportUtils;
+import com.aelitis.net.magneturi.MagnetURIHandler;
 
 public class 
-RelatedContentManager 
+RelatedContentManager
+	implements DistributedDatabaseTransferHandler
 {
-	private static final boolean TRACE = false;
+	private static final boolean 	TRACE = false;
+	private static final boolean	DISABLE_ALL_UI	= !Constants.isCVSVersion();
+
+	private static final int	MAX_HISTORY					= 16;
+	private static final int	MAX_TITLE_LENGTH			= 80;
+	private static final int	MAX_CONCURRENT_PUBLISH		= 2;
+	private static final int	MAX_REMOTE_SEARCH_RESULTS	= 30;
+	
+	private static final int	TEMPORARY_SPACE_DELTA	= 50;
 	
-	private static final int	MAX_HISTORY				= 16;
-	private static final int	MAX_TITLE_LENGTH		= 80;
-	private static final int	MAX_CONCURRENT_PUBLISH	= 2;
+	private static final int	MAX_RANK	= 100;
 	
 	private static final String	CONFIG_FILE 				= "rcm.config";
 	private static final String	PERSIST_DEL_FILE 			= "rcmx.config";
@@ -116,12 +151,14 @@ RelatedContentManager
 	private ByteArrayHashMapEx<DownloadInfo>	download_info_map	= new ByteArrayHashMapEx<DownloadInfo>();
 	private Set<String>							download_priv_set	= new HashSet<String>();
 	
-	private boolean	enabled;
+	private final boolean	enabled;
 	
 	private boolean	ui_enabled;
 	private int		max_search_level;
 	private int		max_results;
 	
+	private AtomicInteger	temporary_space = new AtomicInteger();
+	
 	private int publishing_count = 0;
 	
 	private CopyOnWriteList<RelatedContentManagerListener>	listeners = new CopyOnWriteList<RelatedContentManagerListener>();
@@ -129,6 +166,8 @@ RelatedContentManager
 	private AESemaphore initialisation_complete_sem = new AESemaphore( "RCM:init" );
 
 	private static final int TIMER_PERIOD			= 30*1000;
+	private static final int CONFIG_SAVE_PERIOD		= 60*1000;
+	private static final int CONFIG_SAVE_TICKS		= CONFIG_SAVE_PERIOD/TIMER_PERIOD;
 	private static final int PUBLISH_CHECK_PERIOD	= 30*1000;
 	private static final int PUBLISH_CHECK_TICKS	= PUBLISH_CHECK_PERIOD/TIMER_PERIOD;
 	private static final int SECONDARY_LOOKUP_PERIOD	= 15*60*1000;
@@ -136,6 +175,9 @@ RelatedContentManager
 	private static final int REPUBLISH_PERIOD			= 8*60*60*1000;
 	private static final int REPUBLISH_TICKS			= REPUBLISH_PERIOD/TIMER_PERIOD;
 
+	private static final int INITIAL_PUBLISH_DELAY	= 3*60*1000;
+	private static final int INITIAL_PUBLISH_TICKS	= INITIAL_PUBLISH_DELAY/TIMER_PERIOD;
+	
 	
 	
 	private static final int CONFIG_DISCARD_MILLIS	= 60*1000;
@@ -158,6 +200,8 @@ RelatedContentManager
 	private boolean	secondary_lookup_in_progress;
 	private long	secondary_lookup_complete_time;
 	
+	private DistributedDatabase		ddb;
+	private RCMSearchXFer			transfer_type = new RCMSearchXFer();
 	
 	protected
 	RelatedContentManager()
@@ -208,12 +252,125 @@ RelatedContentManager
 					parameterChanged(
 						String name )
 					{
-						ui_enabled 			= COConfigurationManager.getBooleanParameter( "rcm.ui.enabled", true );
+						ui_enabled 			= COConfigurationManager.getBooleanParameter( "rcm.ui.enabled", true ) && !DISABLE_ALL_UI;
 						max_search_level 	= COConfigurationManager.getIntParameter( "rcm.max_search_level", 3 );
 						max_results		 	= COConfigurationManager.getIntParameter( "rcm.max_results", 500 );
 					}
 				});
 			
+			if ( enabled ){
+				
+				if ( ui_enabled ){
+
+					try{
+						plugin_interface.getUtilities().registerSearchProvider(
+							new SearchProvider()
+							{
+								private Map<Integer,Object>	properties = new HashMap<Integer, Object>();
+								
+								{
+									properties.put( PR_NAME, MessageText.getString( "rcm.search.provider" ));
+									
+									try{
+										URL url = 
+											MagnetURIHandler.getSingleton().registerResource(
+												new MagnetURIHandler.ResourceProvider()
+												{
+													public String
+													getUID()
+													{
+														return( RelatedContentManager.class.getName() + ".1" );
+													}
+													
+													public String
+													getFileType()
+													{
+														return( "png" );
+													}
+															
+													public byte[]
+													getData()
+													{
+														InputStream is = getClass().getClassLoader().getResourceAsStream( "org/gudy/azureus2/ui/icons/rcm.png" );
+														
+														if ( is == null ){
+															
+															return( null );
+														}
+														
+														try{
+															ByteArrayOutputStream	baos = new ByteArrayOutputStream();
+															
+															try{
+																byte[]	buffer = new byte[8192];
+																
+																while( true ){
+										
+																	int	len = is.read( buffer );
+													
+																	if ( len <= 0 ){
+																		
+																		break;
+																	}
+											
+																	baos.write( buffer, 0, len );
+																}
+															}finally{
+																
+																is.close();
+															}
+															
+															return( baos.toByteArray());
+															
+														}catch( Throwable e ){
+															
+															return( null );
+														}
+													}
+												});
+																				
+										properties.put( PR_ICON_URL, url.toExternalForm());
+										
+									}catch( Throwable e ){
+										
+										Debug.out( e );
+									}
+								}
+								
+								public SearchInstance
+								search(
+									Map<String,Object>	search_parameters,
+									SearchObserver		observer )
+								
+									throws SearchException
+								{
+									initialisation_complete_sem.reserve();
+									
+									return( searchRCM( search_parameters, observer ));
+								}
+								
+								public Object
+								getProperty(
+									int			property )
+								{
+									return( properties.get( property ));
+								}
+								
+								public void
+								setProperty(
+									int			property,
+									Object		value )
+								{
+									properties.put( property, value );
+								}
+							});
+					}catch( Throwable e ){
+						
+						Debug.out( "Failed to register search provider" );
+					}
+				}
+			}
+			
 			SimpleTimer.addEvent(
 				"rcm.delay.init",
 				SystemTime.getOffsetTime( 15*1000 ),
@@ -222,7 +379,7 @@ RelatedContentManager
 					public void 
 					perform(
 						TimerEvent event )
-					{
+					{						
 						plugin_interface.addListener(
 							new PluginListener()
 							{
@@ -273,31 +430,49 @@ RelatedContentManager
 													perform(
 														TimerEvent event ) 
 													{
-														if ( ui_enabled ){
-													
-															tick_count++;
-															
-															if ( tick_count % PUBLISH_CHECK_TICKS == 0 ){
+														tick_count++;
+
+														if ( tick_count == 1 ){
 															
-																publish();
+															try{
+																ddb = plugin_interface.getDistributedDatabase();
 															
-																saveRelatedContent();
-															}
-															
-															if ( tick_count % SECONDARY_LOOKUP_TICKS == 0 ){
-
-																secondaryLookup();
+																ddb.addTransferHandler( transfer_type, RelatedContentManager.this );
+																
+															}catch( Throwable e ){
+																
+																Debug.out( e );
 															}
-															
-															if ( tick_count % REPUBLISH_TICKS == 0 ){
-
-																republish();
+														}
+														
+														if ( enabled ){
+																
+															if ( tick_count >= INITIAL_PUBLISH_TICKS ){
+																
+																if ( tick_count % PUBLISH_CHECK_TICKS == 0 ){
+																
+																	publish();
+																}
+																
+																if ( tick_count % SECONDARY_LOOKUP_TICKS == 0 ){
+	
+																	secondaryLookup();
+																}
+																
+																if ( tick_count % REPUBLISH_TICKS == 0 ){
+	
+																	republish();
+																}
+																
+																if ( tick_count % CONFIG_SAVE_TICKS == 0 ){
+																	
+																	saveRelatedContent();
+																}
 															}
-
 														}
 													}
 												});
-										}
+										}										
 									}finally{
 											
 										initialisation_complete_sem.releaseForever();
@@ -374,6 +549,8 @@ RelatedContentManager
 		int		_max )
 	{
 		COConfigurationManager.setParameter( "rcm.max_results", _max );
+		
+		enforceMaxResults( false );
 	}
 	
 	protected void
@@ -426,7 +603,9 @@ RelatedContentManager
 						}
 					}
 					
-					if ( public_net && !TorrentUtils.isReallyPrivate( PluginCoreUtils.unwrap( torrent ))){
+					TOTorrent to_torrent = PluginCoreUtils.unwrap( torrent );
+					
+					if ( public_net && !TorrentUtils.isReallyPrivate( to_torrent )){
 						
 						DownloadManagerState state = PluginCoreUtils.unwrap( download ).getDownloadState();
 
@@ -437,6 +616,22 @@ RelatedContentManager
 						
 						long rand = global_random_id ^ state.getLongParameter( DownloadManagerState.PARAM_RANDOM_SEED );						
 						
+						long cache = state.getLongAttribute( DownloadManagerState.AT_SCRAPE_CACHE );
+
+						int	seeds_leechers;
+						
+						if ( cache == -1 ){
+							
+							seeds_leechers = -1;
+							
+						}else{
+							
+							int seeds 		= (int)((cache>>32)&0x00ffffff);
+							int leechers 	= (int)(cache&0x00ffffff);
+							
+							seeds_leechers 	= (int)((seeds<<16)|(leechers&0xffff));
+						}
+
 						DownloadInfo info = 
 							new DownloadInfo(
 								hash,
@@ -445,7 +640,11 @@ RelatedContentManager
 								(int)rand,
 								torrent.isPrivate()?StringInterner.intern(torrent.getAnnounceURL().getHost()):null,
 								0,
-								torrent.getSize());
+								false,
+								torrent.getSize(),
+								(int)( to_torrent.getCreationDate()/(60*60)),
+								seeds_leechers,
+								(byte)PlatformTorrentUtils.getContentNetworkID( to_torrent ));
 						
 						new_info.add( info );
 						
@@ -671,6 +870,56 @@ RelatedContentManager
 			map.put( "t", tracker );
 		}
 
+		if ( to_info.getLevel() == 0 ){
+			
+			try{
+				Download d = to_info.getRelatedToDownload();
+			
+				if ( d != null ){
+					
+					Torrent torrent = d.getTorrent();
+					
+					if ( torrent != null ){
+						
+						long cnet = PlatformTorrentUtils.getContentNetworkID( PluginCoreUtils.unwrap( torrent ));
+						
+						if ( cnet != ContentNetwork.CONTENT_NETWORK_UNKNOWN ){
+							
+							map.put( "c", new Long( cnet ));
+						}
+						
+						long secs = torrent.getCreationDate();
+						
+						long hours = secs/(60*60);
+						
+						if ( hours > 0 ){
+							
+							map.put( "p", new Long( hours ));
+						}
+					}
+										
+					int leechers 	= -1;
+					int seeds 		= -1;
+					
+					long cache = PluginCoreUtils.unwrap( d ).getDownloadState().getLongAttribute( DownloadManagerState.AT_SCRAPE_CACHE );
+						
+					if ( cache != -1 ){
+							
+						seeds 		= (int)((cache>>32)&0x00ffffff);
+						leechers 	= (int)(cache&0x00ffffff);
+					}
+					
+					if ( leechers > 0 ){
+						map.put( "l", new Long( leechers ));
+					}
+					if ( seeds > 0 ){
+						map.put( "z", new Long( seeds ));
+					}					
+				}
+			}catch( Throwable e ){		
+			}
+		}
+		
 		long	size = to_info.getSize();
 		
 		if ( size != 0 ){
@@ -746,7 +995,39 @@ RelatedContentManager
 							
 							long	size = l_size==null?0:l_size.longValue();
 							
-							analyseResponse( new DownloadInfo( from_info.getHash(), hash, title, rand, tracker, 1, size ), null );
+							Long	cnet	 	= (Long)map.get( "c" );
+							Long	published 	= (Long)map.get( "p" );
+							Long	leechers 	= (Long)map.get( "l" );
+							Long	seeds	 	= (Long)map.get( "z" );
+							
+							// System.out.println( "p=" + published + ", l=" + leechers + ", s=" + seeds );
+							
+							int	seeds_leechers;
+							
+							if ( leechers == null && seeds == null ){
+								
+								seeds_leechers = -1;
+								
+							}else if ( leechers == null ){
+								
+								seeds_leechers = seeds.intValue()<<16;
+								
+							}else if ( seeds == null ){
+								
+								seeds_leechers = leechers.intValue()&0xffff;
+								
+							}else{
+								
+								seeds_leechers = (seeds.intValue()<<16)|(leechers.intValue()&0xffff);
+							}
+								
+							analyseResponse( 
+								new DownloadInfo( 
+										from_info.getHash(), hash, title, rand, tracker, 1, false, size, 
+										published==null?0:published.intValue(),
+										seeds_leechers,
+										(byte)(cnet==null?ContentNetwork.CONTENT_NETWORK_UNKNOWN:cnet.byteValue())), 
+								null );
 							
 						}catch( Throwable e ){							
 						}
@@ -769,17 +1050,19 @@ RelatedContentManager
 					{
 						boolean	do_it;
 						
-						if ( diversified || hits >= 20 ){
+						// System.out.println( from_hash + ": hits=" + hits + ", div=" + diversified );
+						
+						if ( diversified || hits >= 10 ){
 							
 							do_it = false;
 							
-						}else if ( hits <= 10 ){
+						}else if ( hits <= 5 ){
 							
 							do_it = true;
 														
 						}else{
 													
-							do_it = RandomUtils.nextInt( hits - 10 + 1 ) == 0;
+							do_it = RandomUtils.nextInt( hits - 5 + 1 ) == 0;
 						}
 							
 						if ( do_it ){
@@ -838,23 +1121,19 @@ RelatedContentManager
 					}
 				});
 	}
-		
+			
 	public void
 	lookupContent(
-		Download							download,
+		final byte[]						hash,
 		final RelatedContentLookupListener	listener )
 	
 		throws ContentException
 	{
-		Torrent t = download.getTorrent();
-		
-		if ( t == null ){
+		if ( hash == null ){
 			
-			throw( new ContentException( "Torrent not available" ));
+			throw( new ContentException( "hash is null" ));
 		}
 
-		final byte[] hash = t.getHash();
-		
 		if ( 	!initialisation_complete_sem.isReleasedForever() ||
 				( dht_plugin != null && dht_plugin.isInitialising())){
 			
@@ -869,7 +1148,7 @@ RelatedContentManager
 						try{
 							initialisation_complete_sem.reserve();
 							
-							lookupContentSupport( hash, 0, listener );
+							lookupContentSupport( hash, 0, true, listener );
 							
 						}catch( ContentException e ){
 							
@@ -879,7 +1158,7 @@ RelatedContentManager
 				});
 		}else{
 			
-			lookupContentSupport( hash, 0, listener );
+			lookupContentSupport( hash, 0, true, listener );
 		}
 	}
 	
@@ -887,6 +1166,7 @@ RelatedContentManager
 	lookupContentSupport(
 		final byte[]						from_hash,
 		final int							level,
+		final boolean						explicit,
 		final RelatedContentLookupListener	listener )
 	
 		throws ContentException
@@ -1029,10 +1309,36 @@ RelatedContentManager
 								
 								long	size = l_size==null?0:l_size.longValue();
 
+								Long	cnet	 	= (Long)map.get( "c" );
+								Long	published 	= (Long)map.get( "p" );
+								Long	leechers 	= (Long)map.get( "l" );
+								Long	seeds	 	= (Long)map.get( "z" );
+
+								int	seeds_leechers;
+								
+								if ( leechers == null && seeds == null ){
+									
+									seeds_leechers = -1;
+									
+								}else if ( leechers == null ){
+									
+									seeds_leechers = seeds.intValue()<<16;
+									
+								}else if ( seeds == null ){
+									
+									seeds_leechers = leechers.intValue()&0xffff;
+									
+								}else{
+									
+									seeds_leechers = (seeds.intValue()<<16)|(leechers.intValue()&0xffff);
+								}
 								analyseResponse( 
 									new DownloadInfo( 
-										from_hash, hash, title, rand, tracker, level+1, size ),
-										listener==null?null:manager_listener );
+										from_hash, hash, title, rand, tracker, level+1, explicit, size,
+										published==null?0:published.intValue(),
+										seeds_leechers,
+										(byte)(cnet==null?ContentNetwork.CONTENT_NETWORK_UNKNOWN:cnet.byteValue())),
+									listener==null?null:manager_listener );
 								
 							}catch( Throwable e ){							
 							}
@@ -1235,6 +1541,7 @@ RelatedContentManager
 			lookupContentSupport( 
 				sl.getHash(),
 				sl.getLevel(),
+				false,
 				new RelatedContentLookupListener()
 				{
 					public void
@@ -1294,7 +1601,7 @@ RelatedContentManager
 									TimerEvent event ) 
 								{
 									try{					
-										lookupContentSupport( next_sl.getHash(), next_sl.getLevel(), listener );
+										lookupContentSupport( next_sl.getHash(), next_sl.getLevel(), false, listener );
 										
 									}catch( Throwable e ){
 										
@@ -1649,7 +1956,7 @@ RelatedContentManager
 	{
 		Map<String,DownloadInfo> related_content = content_cache.related_content;
 		
-		if ( related_content.size() < max_results ){
+		if ( related_content.size() < max_results + temporary_space.get()){
 			
 			return( true );
 		}
@@ -1670,6 +1977,11 @@ RelatedContentManager
 			
 			DownloadInfo info = entry.getValue();
 			
+			if ( info.isExplicit()){
+				
+				continue;
+			}
+			
 			int	info_level = info.getLevel();
 			
 			if ( info_level >= level ){
@@ -1787,6 +2099,630 @@ RelatedContentManager
 				});
 	}
 	
+	protected List<RelatedContent>
+	matchContent(
+		String		term )
+	{
+			// term is made up of space separated bits - all bits must match
+			// each bit can be prefixed by + or -, a leading - means 'bit doesn't match'. + doesn't mean anything
+			// each bit (with prefix removed) can be "(" regexp ")"
+			// if bit isn't regexp but has "|" in it it is turned into a regexp so a|b means 'a or b'
+		
+		List<RelatedContent>	result = new ArrayList<RelatedContent>();
+		
+		RelatedContent[] content = getRelatedContent();
+		
+		String[]	 bits = term.toLowerCase().split( " " );
+
+		int[]		bit_types 		= new int[bits.length];
+		Pattern[]	bit_patterns 	= new Pattern[bits.length];
+		
+		for (int i=0;i<bits.length;i++){
+			
+			String bit = bits[i] = bits[i].trim();
+			
+			if ( bit.length() > 0 ){
+				
+				char	c = bit.charAt(0);
+				
+				if ( c == '+' ){
+					
+					bit_types[i] = 1;
+					
+					bit = bits[i] = bit.substring(1);
+					
+				}else if ( c == '-' ){
+					
+					bit_types[i] = 2;
+					
+					bit = bits[i] = bit.substring(1);
+				}
+				
+				if ( bit.startsWith( "(" ) && bit.endsWith((")"))){
+					
+					bit = bit.substring( 1, bit.length()-1 );
+					
+					try{
+						bit_patterns[i] = Pattern.compile( bit, Pattern.CASE_INSENSITIVE );
+						
+					}catch( Throwable e ){
+					}
+				}else if ( bit.contains( "|" )){
+					
+					try{
+						bit_patterns[i] = Pattern.compile( bit, Pattern.CASE_INSENSITIVE );
+						
+					}catch( Throwable e ){
+					}
+				}
+			}
+		}
+			
+		
+		for ( final RelatedContent c: content ){
+			
+			String title = c.getTitle().toLowerCase();
+			
+			boolean	match 			= true;
+			boolean	at_least_one 	= false;
+			
+			for (int i=0;i<bits.length;i++){
+				
+				String bit = bits[i];
+				
+				if ( bit.length() > 0 ){
+					
+					boolean	hit;
+					
+					if ( bit_patterns[i] == null ){
+					
+						hit = title.contains( bit );
+						
+					}else{
+					
+						hit = bit_patterns[i].matcher( title ).find();
+					}
+					
+					int	type = bit_types[i];
+					
+					if ( hit ){
+												
+						if ( type == 2 ){
+							
+							match = false;
+							
+							break;
+							
+						}else{
+							
+							at_least_one = true;
+
+						}
+					}else{
+						
+						if ( type == 2 ){
+						
+							at_least_one = true;
+							
+						}else{
+							
+							match = false;
+						
+							break;
+						}
+					}
+				}
+			}
+			
+			if ( match && at_least_one ){
+				
+				result.add( c );
+			}
+		}
+		
+		return( result );
+	}
+	
+	protected SearchInstance
+	searchRCM(
+		Map<String,Object>		search_parameters,
+		final SearchObserver	observer )
+	
+		throws SearchException
+	{
+		final String	term = (String)search_parameters.get( SearchProvider.SP_SEARCH_TERM );
+		
+		final SearchInstance si = 
+			new SearchInstance()
+			{
+				public void
+				cancel()
+			{
+					Debug.out( "Cancelled" );
+				}
+			};
+			
+		if ( term == null ){
+		
+			observer.complete();
+			
+		}else{
+		
+			new AEThread2( "RCM:search", true )
+			{
+				public void
+				run()
+				{
+					final Set<String>	titles_or_hashes = new HashSet<String>();
+					
+					try{				
+						List<RelatedContent>	matches = matchContent( term );
+							
+						for ( final RelatedContent c: matches ){
+							
+							titles_or_hashes.add( c.getHash()==null?c.getTitle():Base32.encode(c.getHash()));
+							
+							SearchResult result = 
+								new SearchResult()
+								{
+									public Object
+									getProperty(
+										int		property_name )
+									{
+										if ( property_name == SearchResult.PR_NAME ){
+											
+											return( c.getTitle());
+											
+										}else if ( property_name == SearchResult.PR_SIZE ){
+											
+											return( c.getSize());
+											
+										}else if ( property_name == SearchResult.PR_RANK ){
+											
+												// this rank isn't that accurate, scale down
+											
+											return( new Long( c.getRank() / 4 ));
+											
+										}else if ( property_name == SearchResult.PR_SEED_COUNT ){
+											
+											return( new Long( c.getSeeds()));
+											
+										}else if ( property_name == SearchResult.PR_LEECHER_COUNT ){
+											
+											return( new Long( c.getLeechers()));
+											
+										}else if ( property_name == SearchResult.PR_SUPER_SEED_COUNT ){
+											
+											if ( c.getContentNetwork() != ContentNetwork.CONTENT_NETWORK_UNKNOWN ){
+												
+												return( new Long( 1 ));
+												
+											}else{
+												
+												return( new Long( 0 ));
+											}
+										}else if ( property_name == SearchResult.PR_PUB_DATE ){
+												
+											long	date = c.getPublishDate();
+											
+											if ( date <= 0 ){
+												
+												return( null );
+											}
+											
+											return( new Date( date ));
+											
+										}else if ( 	property_name == SearchResult.PR_DOWNLOAD_LINK ||
+													property_name == SearchResult.PR_DOWNLOAD_BUTTON_LINK ){
+											
+											byte[] hash = c.getHash();
+											
+											if ( hash != null ){
+												
+												return( TorrentUtils.getMagnetURI( hash ));
+											}
+										}
+										
+										return( null );
+									}
+								};
+								
+							observer.resultReceived( si, result );
+						}
+					}finally{
+						
+						try{
+							int	max_contacts = 20;
+							
+							DHT[]	dhts = dht_plugin.getDHTs();
+	
+							Set<InetSocketAddress>	addresses = new HashSet<InetSocketAddress>();
+							
+							for ( DHT dht: dhts ){
+							
+								DHTTransportContact[] contacts = dht.getTransport().getReachableContacts();
+								
+								for ( DHTTransportContact c: contacts ){
+									
+									if ( c.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL ){
+										
+										addresses.add( c.getAddress());
+									}
+								}
+							}
+							
+							if ( addresses.size() < max_contacts ){
+								
+								for ( DHT dht: dhts ){
+									
+									DHTTransportContact[] contacts = dht.getTransport().getRecentContacts();
+	
+									for ( DHTTransportContact c: contacts ){
+										
+										if ( c.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL ){
+											
+											addresses.add( c.getAddress());
+											
+											if ( addresses.size() >= max_contacts ){
+												
+												break;
+											}
+										}
+									}
+									
+									if ( addresses.size() >= max_contacts ){
+										
+										break;
+									}
+								}
+							}
+							
+							List<InetSocketAddress>	list = new ArrayList<InetSocketAddress>( addresses );
+							
+							Collections.shuffle( list );
+							
+							List<DistributedDatabaseContact>	ddb_contacts = new ArrayList<DistributedDatabaseContact>();
+							
+							for (int i=0;i<Math.min( list.size(), max_contacts );i++){
+								
+								try{				
+									ddb_contacts.add( ddb.importContact( list.get(i), DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL ));
+									
+								}catch( Throwable e ){
+								}
+							}
+							
+							long	start		= SystemTime.getMonotonousTime();
+							long	max			= 25*1000;
+							
+							final AESemaphore	sem = new AESemaphore( "RCM:rems" );
+							
+							int	sent = 0;
+							
+							final int[]			done = {0};
+							
+							for (int i=0;i<ddb_contacts.size();i++){
+								
+								final DistributedDatabaseContact c = ddb_contacts.get( i );
+																
+								new AEThread2( "RCM:rems", true )
+								{
+									public void
+									run()
+									{
+										try{
+											sendRemoteSearch( si, titles_or_hashes, c, term, observer );
+																						
+										}finally{
+											
+											synchronized( done ){
+											
+												done[0]++;
+											}
+											
+											sem.release();
+										}
+									}
+								}.start();
+								
+								sent++;
+								
+								synchronized( done ){
+									
+									if ( done[0] >= ddb_contacts.size() / 2 ){
+										
+										start		= SystemTime.getMonotonousTime();
+										max			= 5*1000;
+										
+										break;
+									}
+								}
+								
+								if ( i > 5 ){
+									
+									try{
+										Thread.sleep( 500 );
+										
+									}catch( Throwable e ){
+									}
+								}
+							}
+							
+							for (int i=0;i<sent;i++){
+								
+								if ( done[0] > sent*2/3 ){
+									
+									break;
+								}
+								
+								long	elapsed = SystemTime.getMonotonousTime() - start;
+								
+								if ( elapsed < max ){
+									
+									sem.reserve( max - elapsed );
+									
+								}else{
+									
+									break;
+								}
+							}
+						}finally{
+													
+							observer.complete();
+						}
+					}
+				}
+			}.start();
+		}
+		
+		return( si );
+	}
+	
+	protected void
+	sendRemoteSearch(
+		SearchInstance					si,
+		Set<String>						titles_or_hashes,
+		DistributedDatabaseContact		contact,
+		String							term,
+		SearchObserver					observer )
+	{
+		try{
+			Map<String,Object>	request = new HashMap<String,Object>();
+			
+			request.put( "t", term );
+		
+			DistributedDatabaseKey key = ddb.createKey( BEncoder.encode( request ));
+			
+			DistributedDatabaseValue value = 
+				contact.read( 
+					new DistributedDatabaseProgressListener()
+					{
+						public void
+						reportSize(
+							long	size )
+						{	
+						}
+						
+						public void
+						reportActivity(
+							String	str )
+						{	
+						}
+						
+						public void
+						reportCompleteness(
+							int		percent )
+						{
+						}
+					},
+					transfer_type,
+					key,
+					10000 );
+			
+			// System.out.println( "search result=" + value );
+			
+			if ( value == null ){
+				
+				return;
+			}
+			
+			Map<String,Object> reply = (Map<String,Object>)BDecoder.decode((byte[])value.getValue( byte[].class ));
+			
+			List<Map<String,Object>>	list = (List<Map<String,Object>>)reply.get( "l" );
+			
+			for ( final Map<String,Object> map: list ){
+				
+				final String title = ImportExportUtils.importString( map, "n" );
+				
+				byte[] hash = (byte[])map.get( "h" );
+				
+				String	title_or_hash = hash==null?title:Base32.encode( hash );
+					
+				if ( titles_or_hashes.contains( title_or_hash )){
+					
+					continue;
+				}
+				
+				titles_or_hashes.add( title_or_hash );
+
+				SearchResult result = 
+					new SearchResult()
+					{
+						public Object
+						getProperty(
+							int		property_name )
+						{
+							try{
+								if ( property_name == SearchResult.PR_NAME ){
+									
+									return( title );
+									
+								}else if ( property_name == SearchResult.PR_SIZE ){
+									
+									return( ImportExportUtils.importLong( map, "s" ));
+									
+								}else if ( property_name == SearchResult.PR_RANK ){
+									
+									return( ImportExportUtils.importLong( map, "r" ) / 4 );
+									
+								}else if ( property_name == SearchResult.PR_SUPER_SEED_COUNT ){
+									
+									long cnet = ImportExportUtils.importLong( map, "c", ContentNetwork.CONTENT_NETWORK_UNKNOWN );
+									
+									if ( cnet == ContentNetwork.CONTENT_NETWORK_UNKNOWN ){
+										
+										return( 0L );
+										
+									}else{
+										
+										return( 1L );
+									}
+								}else if ( property_name == SearchResult.PR_SEED_COUNT ){
+									
+									return( ImportExportUtils.importLong( map, "z" ));
+									
+								}else if ( property_name == SearchResult.PR_LEECHER_COUNT ){
+									
+									return( ImportExportUtils.importLong( map, "l" ));
+									
+								}else if ( property_name == SearchResult.PR_PUB_DATE ){
+									
+									long date = ImportExportUtils.importLong( map, "p", 0 )*60*60*1000L;
+									
+									if ( date <= 0 ){
+										
+										return( null );
+									}
+									
+									return( new Date( date ));
+									
+								}else if ( 	property_name == SearchResult.PR_DOWNLOAD_LINK ||
+											property_name == SearchResult.PR_DOWNLOAD_BUTTON_LINK ){
+									
+									byte[] hash = (byte[])map.get( "h" );
+									
+									if ( hash != null ){
+										
+										return( TorrentUtils.getMagnetURI( hash ));
+									}
+								}
+							}catch( Throwable e ){
+							}
+							
+							return( null );
+						}
+					};
+					
+				observer.resultReceived( si, result );
+			}
+		}catch( Throwable e ){
+		}
+	}
+	
+	protected Map<String,Object>
+	receiveRemoteSearch(
+		Map<String,Object>		request )
+	{
+		Map<String,Object>	response = new HashMap<String,Object>();
+		
+		try{
+			String	term = ImportExportUtils.importString( request, "t" );
+		
+			if ( term != null ){
+				
+				List<RelatedContent>	matches = matchContent( term );
+
+				if ( matches.size() > MAX_REMOTE_SEARCH_RESULTS ){
+					
+					Collections.sort(
+						matches,
+						new Comparator<RelatedContent>()
+						{
+							public int 
+							compare(
+								RelatedContent o1,
+								RelatedContent o2) 
+							{
+								return( o2.getRank() - o1.getRank());
+							}
+						});
+				}
+				
+				List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
+				
+				for (int i=0;i<Math.min( matches.size(),MAX_REMOTE_SEARCH_RESULTS);i++){
+					
+					RelatedContent	c = matches.get(i);
+					
+					Map<String,Object>	map = new HashMap<String, Object>();
+					
+					list.add( map );
+					
+					ImportExportUtils.exportString( map, "n", c.getTitle());
+					ImportExportUtils.exportLong( map, "s", c.getSize());
+					ImportExportUtils.exportLong( map, "r", c.getRank());
+					ImportExportUtils.exportLong( map, "d", c.getLastSeenSecs());
+					ImportExportUtils.exportLong( map, "p", c.getPublishDate()/(60*60*1000));
+					ImportExportUtils.exportLong( map, "l", c.getLeechers());
+					ImportExportUtils.exportLong( map, "z", c.getSeeds());
+					ImportExportUtils.exportLong( map, "c", c.getContentNetwork());
+					
+					byte[] hash = c.getHash();
+					
+					if ( hash != null ){
+						
+						map.put( "h", hash );
+					}
+				}
+				
+				response.put( "l", list );
+			}
+		}catch( Throwable e ){
+		}
+		
+		return( response );
+	}
+	
+	public DistributedDatabaseValue
+	read(
+		DistributedDatabaseContact			contact,
+		DistributedDatabaseTransferType		type,
+		DistributedDatabaseKey				ddb_key )
+	
+		throws DistributedDatabaseException
+	{
+		Object	o_key = ddb_key.getKey();
+		
+		try{
+			byte[]	key = (byte[])o_key;
+			
+				// TODO bloom
+			
+			Map<String,Object>	request = BDecoder.decode( key );
+			
+			Map<String,Object>	result = receiveRemoteSearch( request );
+			
+			return( ddb.createValue( BEncoder.encode( result )));
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+			
+			return( null );
+		}
+	}
+	
+	public void
+	write(
+		DistributedDatabaseContact			contact,
+		DistributedDatabaseTransferType		type,
+		DistributedDatabaseKey				key,
+		DistributedDatabaseValue			value )
+	
+		throws DistributedDatabaseException
+	{
+	}
+	
 	protected void
 	setConfigDirty()
 	{
@@ -1983,6 +2919,9 @@ RelatedContentManager
 						
 						Debug.out( e );
 					}
+					
+					enforceMaxResults( cc, false );
+
 				}else{
 					
 					if ( TRACE ){
@@ -1991,7 +2930,7 @@ RelatedContentManager
 				}
 				
 				content_cache_ref = cc;
-				
+								
 				return( cc );
 			}
 		}finally{
@@ -2348,6 +3287,97 @@ RelatedContentManager
 	}
 	
 	public void
+	reserveTemporarySpace()
+	{
+		temporary_space.addAndGet( TEMPORARY_SPACE_DELTA );
+	}
+	
+	public void
+	releaseTemporarySpace()
+	{
+		boolean	reset_explicit = temporary_space.addAndGet( -TEMPORARY_SPACE_DELTA ) == 0;
+		
+		enforceMaxResults( reset_explicit );
+	}
+	
+	protected void
+	enforceMaxResults(
+		boolean reset_explicit )
+	{
+		synchronized( this ){
+	
+			ContentCache	content_cache = loadRelatedContent();
+			
+			enforceMaxResults( content_cache, reset_explicit );
+		}
+	}
+	
+	protected void
+	enforceMaxResults(
+		ContentCache		content_cache,
+		boolean				reset_explicit )	
+	{
+		Map<String,DownloadInfo>		related_content			= content_cache.related_content;
+
+		int num_to_remove = related_content.size() - ( max_results + temporary_space.get());
+		
+		if ( num_to_remove > 0 ){
+			
+			List<DownloadInfo>	infos = new ArrayList<DownloadInfo>(related_content.values());
+				
+			if ( reset_explicit ){
+				
+				for ( DownloadInfo info: infos ){
+					
+					if ( info.isExplicit()){
+						
+						info.setExplicit( false );
+					}
+				}
+			}
+			
+			Collections.sort(
+				infos,
+				new Comparator<DownloadInfo>()
+				{
+					public int 
+					compare(
+						DownloadInfo o1, 
+						DownloadInfo o2) 
+					{
+						int res = o2.getLevel() - o1.getLevel();
+						
+						if ( res != 0 ){
+							
+							return( res );
+						}
+						
+						res = o1.getRank() - o2.getRank();
+						
+						if ( res != 0 ){
+							
+							return( res );
+						}
+						
+						return( o1.getLastSeenSecs() - o2.getLastSeenSecs());
+					}
+				});
+
+			List<RelatedContent> to_remove = new ArrayList<RelatedContent>();
+			
+			for (int i=0;i<Math.min( num_to_remove, infos.size());i++ ){
+				
+				to_remove.add( infos.get(i));
+			}
+			
+			if ( to_remove.size() > 0 ){
+					
+				delete( to_remove.toArray( new RelatedContent[to_remove.size()]), content_cache, false );
+			}
+		}
+	}
+	
+	public void
 	addListener(
 		RelatedContentManagerListener		listener )
 	{
@@ -2416,6 +3446,10 @@ RelatedContentManager
 			ImportExportUtils.exportString( info_map, "t", info.getTracker());
 			ImportExportUtils.exportLong( info_map, "z", info.getSize());
 			
+			ImportExportUtils.exportInt( info_map, "p", (int)( info.getPublishDate()/(60*60*1000)));
+			ImportExportUtils.exportInt( info_map, "q", (info.getSeeds()<<16)|(info.getLeechers()&0xffff));
+			ImportExportUtils.exportInt( info_map, "c", (int)info.getContentNetwork());
+
 			if ( cc != null ){
 							
 				ImportExportUtils.exportBoolean( info_map, "u", info.isUnread());
@@ -2446,9 +3480,13 @@ RelatedContentManager
 			String	tracker	= ImportExportUtils.importString( info_map, "t" );
 			long	size	= ImportExportUtils.importLong( info_map, "z" );
 			
+			int		date 			=  ImportExportUtils.importInt( info_map, "p", 0 );
+			int		seeds_leechers 	=  ImportExportUtils.importInt( info_map, "q", -1 );
+			byte	cnet 			=  (byte)ImportExportUtils.importInt( info_map, "c", (int)ContentNetwork.CONTENT_NETWORK_UNKNOWN );
+			
 			if ( cc == null ){
 			
-				return( new DownloadInfo( hash, hash, title, rand, tracker, 0, size ));
+				return( new DownloadInfo( hash, hash, title, rand, tracker, 0, false, size, date, seeds_leechers, cnet ));
 				
 			}else{
 				
@@ -2460,7 +3498,7 @@ RelatedContentManager
 				
 				int	level = ImportExportUtils.importInt( info_map, "e" );
 				
-				return( new DownloadInfo( hash, title, rand, tracker, unread, rand_list, last_seen, level, size, cc ));
+				return( new DownloadInfo( hash, title, rand, tracker, unread, rand_list, last_seen, level, size, date, seeds_leechers, cnet, cc ));
 			}
 		}catch( Throwable e ){
 			
@@ -2480,6 +3518,9 @@ RelatedContentManager
 		private int[]			rand_list;
 		private int				last_seen;
 		private int				level;
+		private boolean			explicit;
+		
+			// we *need* this reference here to maange garbage collection correctly
 		
 		private ContentCache	cc;
 		
@@ -2491,12 +3532,17 @@ RelatedContentManager
 			int			_rand,
 			String		_tracker,
 			int			_level,
-			long		_size )
+			boolean		_explicit,
+			long		_size,
+			int			_date,
+			int			_seeds_leechers,
+			byte		_cnet )
 		{
-			super( _related_to, _title, _hash, _tracker, _size );
+			super( _related_to, _title, _hash, _tracker, _size, _date, _seeds_leechers, _cnet );
 			
 			rand		= _rand;
 			level		= _level;
+			explicit	= _explicit;
 			
 			updateLastSeen();
 		}
@@ -2512,9 +3558,12 @@ RelatedContentManager
 			int				_last_seen,
 			int				_level,
 			long			_size,
+			int				_date,
+			int				_seeds_leechers,
+			byte			_cnet,
 			ContentCache	_cc )
 		{
-			super( _title, _hash, _tracker, _size );
+			super( _title, _hash, _tracker, _size, _date, _seeds_leechers, _cnet );
 			
 			rand		= _rand;
 			unread		= _unread;
@@ -2522,6 +3571,18 @@ RelatedContentManager
 			last_seen	= _last_seen;
 			level		= _level;
 			cc			= _cc;
+			
+			if ( rand_list != null ){
+				
+				if ( rand_list.length > MAX_RANK ){
+					
+					int[] temp = new int[ MAX_RANK ];
+					
+					System.arraycopy( rand_list, 0, temp, 0, MAX_RANK );
+						
+					rand_list = temp;
+				}
+			}
 		}
 		
 		protected boolean
@@ -2556,7 +3617,7 @@ RelatedContentManager
 						}
 					}
 					
-					if ( !match ){
+					if ( !match && rand_list.length < MAX_RANK ){
 						
 						int	len = rand_list.length;
 						
@@ -2578,6 +3639,32 @@ RelatedContentManager
 					
 					result = true;
 				}
+				
+				long cn =  info.getContentNetwork();
+				
+				if ( 	cn != ContentNetwork.CONTENT_NETWORK_UNKNOWN && 
+						getContentNetwork() == ContentNetwork.CONTENT_NETWORK_UNKNOWN ){
+					
+					setContentNetwork( cn );
+				}
+				
+				int sl = info.getSeedsLeechers();
+				
+				if ( sl != -1 && sl != getSeedsLeechers()){
+					
+					setSeedsLeechers( sl );
+					
+					result = true;
+				}
+				
+				int	d = info.getDateHours();
+				
+				if ( d > 0 && d != getDateHours()){
+					
+					setDateHours( d );
+					
+					result = true;
+				}
 			}
 			
 			return( result );
@@ -2589,6 +3676,19 @@ RelatedContentManager
 			return( level );
 		}
 		
+		protected boolean
+		isExplicit()
+		{
+			return( explicit );
+		}
+		
+		protected void
+		setExplicit(
+			boolean		b )
+		{
+			explicit	= b;
+		}
+		
 		protected void
 		updateLastSeen()
 		{
@@ -2706,7 +3806,7 @@ RelatedContentManager
 		public String
 		getString()
 		{
-			return( super.getString() + ", " + rand );
+			return( super.getString() + ", " + rand + ", rl=" + rand_list + ", last_seen=" + last_seen + ", level=" + level );
 		}
 	}
 	
@@ -2744,4 +3844,10 @@ RelatedContentManager
 			return( level );
 		}
 	}
+	
+	protected class
+	RCMSearchXFer
+		implements DistributedDatabaseTransferType
+	{	
+	}
 }
diff --git a/com/aelitis/azureus/core/crypto/VuzeCryptoManager.java b/com/aelitis/azureus/core/crypto/VuzeCryptoManager.java
index 4777b3f..599c737 100644
--- a/com/aelitis/azureus/core/crypto/VuzeCryptoManager.java
+++ b/com/aelitis/azureus/core/crypto/VuzeCryptoManager.java
@@ -21,24 +21,9 @@
 
 package com.aelitis.azureus.core.crypto;
 
-import java.util.Iterator;
 
-import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.util.AEThread2;
-import org.gudy.azureus2.core3.util.Base32;
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.plugins.Plugin;
-import org.gudy.azureus2.plugins.PluginInterface;
-
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.AzureusCoreLifecycleAdapter;
 import com.aelitis.azureus.core.security.*;
-import com.aelitis.azureus.core.util.CopyOnWriteList;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPlugin;
+
 
 public class 
 VuzeCryptoManager 
@@ -56,18 +41,19 @@ VuzeCryptoManager
 		return( singleton );
 	}
 	
-	private boolean			init_tried;
+	//private boolean			init_tried;
 	
 	private CryptoManager	crypt_man;
-	private CopyOnWriteList	listeners = new CopyOnWriteList();
+	//private CopyOnWriteList	listeners = new CopyOnWriteList();
 	
-	private volatile CryptoManagerPasswordHandler.passwordDetails	session_pw;
+	//private volatile CryptoManagerPasswordHandler.passwordDetails	session_pw;
 	
 	protected
 	VuzeCryptoManager()
 	{
 		crypt_man = CryptoManagerFactory.getSingleton();
 		
+		/*
 		crypt_man.addPasswordHandler(
 			new CryptoManagerPasswordHandler()
 			{
@@ -192,8 +178,10 @@ VuzeCryptoManager
 				});
 			
 		}
+		*/
 	}
 	
+	/*
 	protected void
 	initialise(
 		AzureusCore		core )
@@ -232,7 +220,7 @@ VuzeCryptoManager
 						
 						}catch( Throwable e ){
 							
-							VuzeBuddyManager.log( "CRYPTO: Failed to set default password handler type: " + Debug.getNestedExceptionMessage( e ));
+							Debug.out( "CRYPTO: Failed to set default password handler type: " + Debug.getNestedExceptionMessage( e ));
 						}
 					}
 					
@@ -242,18 +230,20 @@ VuzeCryptoManager
 					
 					COConfigurationManager.save();
 					
-					VuzeBuddyManager.log( "CRYPTO: initialised buddy plugin and default handler type" );
+					Debug.out( "CRYPTO: initialised buddy plugin and default handler type" );
 				}
 			}
 		}
 	}
-	
+	*/
+		
 	public byte[]
 	getPlatformAZID()
 	{
 		return( crypt_man.getSecureID());
 	}
 
+	/*
 	public String
 	getPublicKey(
 		String		reason )
@@ -274,11 +264,7 @@ VuzeCryptoManager
 	{
 		return crypt_man.getECCHandler().peekPublicKey() != null;
 	}
-	
-		/**
-		 * Remove cached password
-		 */
-	
+		
 	public void
 	clearPassword()
 	{
@@ -286,11 +272,6 @@ VuzeCryptoManager
 	
 		crypt_man.clearPasswords( CryptoManagerPasswordHandler.HANDLER_TYPE_SYSTEM );
 	}
-	
-		/**
-		 * Explicitly set password instead of waiting for listener trigger
-		 * @param pw
-		 */
 		 
 	public void
 	setPassword(
@@ -343,4 +324,5 @@ VuzeCryptoManager
 	{
 		listeners.remove( listener );
 	}
+	*/
 }
diff --git a/com/aelitis/azureus/core/devices/Device.java b/com/aelitis/azureus/core/devices/Device.java
index 34448eb..e66d053 100644
--- a/com/aelitis/azureus/core/devices/Device.java
+++ b/com/aelitis/azureus/core/devices/Device.java
@@ -31,6 +31,7 @@ Device
 	public static final int DT_CONTENT_DIRECTORY	= 2;
 	public static final int DT_MEDIA_RENDERER		= 3;
 	public static final int DT_INTERNET				= 4;
+	public static final int DT_OFFLINE_DOWNLOADER	= 5;
 		
 	public int
 	getType();
@@ -108,6 +109,14 @@ Device
 	public String
 	getError();
 	
+	public void
+	addListener(
+		DeviceListener		listener );
+	
+	public void
+	removeListener(
+		DeviceListener		listener );
+	
 	public String
 	getString();
 	
diff --git a/com/aelitis/azureus/core/devices/DeviceListener.java b/com/aelitis/azureus/core/devices/DeviceListener.java
new file mode 100644
index 0000000..cc031f1
--- /dev/null
+++ b/com/aelitis/azureus/core/devices/DeviceListener.java
@@ -0,0 +1,30 @@
+/*
+ * Created on Sep 2, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.devices;
+
+public interface 
+DeviceListener 
+{
+	public void
+	deviceChanged(
+		Device		device );
+}
diff --git a/com/aelitis/azureus/core/devices/DeviceManager.java b/com/aelitis/azureus/core/devices/DeviceManager.java
index 12725c2..20ec95a 100644
--- a/com/aelitis/azureus/core/devices/DeviceManager.java
+++ b/com/aelitis/azureus/core/devices/DeviceManager.java
@@ -57,20 +57,9 @@ DeviceManager
 	setRSSPublishEnabled(
 		boolean		enabled );
 
-	public boolean
-	isRSSLocalOnly();
-	
-	public void
-	setRSSLocalOnly(
-		boolean	local_only );
+	public String
+	getRSSLink();
 	
-	public int
-	getRSSPort();
-	
-	public void
-	setRSSPort(
-		int		port );
-
 	public UnassociatedDevice[]
 	getUnassociatedDevices();
 	
@@ -87,6 +76,16 @@ DeviceManager
 	public boolean
 	isBusy();
 	
+	public DeviceOfflineDownloaderManager
+	getOfflineDownlaoderManager();
+	
+	public boolean
+	isTiVoEnabled();
+	
+	public void
+	setTiVoEnabled(
+		boolean	enabled );
+	
 	public void
 	addListener(
 		DeviceManagerListener		listener );
diff --git a/com/aelitis/azureus/core/devices/DeviceOfflineDownload.java b/com/aelitis/azureus/core/devices/DeviceOfflineDownload.java
new file mode 100644
index 0000000..f50b1d4
--- /dev/null
+++ b/com/aelitis/azureus/core/devices/DeviceOfflineDownload.java
@@ -0,0 +1,40 @@
+/*
+ * Created on Sep 1, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.devices;
+
+import org.gudy.azureus2.plugins.download.Download;
+
+public interface 
+DeviceOfflineDownload 
+{
+	public Download
+	getDownload();
+	
+	public boolean
+	isTransfering();
+	
+	public long
+	getCurrentTransferSize();
+	
+	public long
+	getRemaining();
+}
diff --git a/com/aelitis/azureus/core/devices/DeviceOfflineDownloader.java b/com/aelitis/azureus/core/devices/DeviceOfflineDownloader.java
new file mode 100644
index 0000000..f1c1a0f
--- /dev/null
+++ b/com/aelitis/azureus/core/devices/DeviceOfflineDownloader.java
@@ -0,0 +1,62 @@
+/*
+ * Created on Jan 27, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.devices;
+
+public interface 
+DeviceOfflineDownloader
+	extends Device
+{
+	public boolean
+	isEnabled();
+	
+	public void
+	setEnabled(
+		boolean		b );
+	
+	public boolean
+	hasShownFTUX();
+	
+	public void
+	setShownFTUX();
+	
+	public String
+	getManufacturer();
+	
+	public long
+	getSpaceAvailable()
+	
+		throws DeviceManagerException;
+	
+	public int
+	getTransferingCount();
+
+	public DeviceOfflineDownload[]
+	getDownloads();
+		
+	public void
+	addListener(
+		DeviceOfflineDownloaderListener		listener );
+	
+	public void
+	removeListener(
+		DeviceOfflineDownloaderListener		listener );
+}
diff --git a/com/aelitis/azureus/core/devices/DeviceOfflineDownloaderListener.java b/com/aelitis/azureus/core/devices/DeviceOfflineDownloaderListener.java
new file mode 100644
index 0000000..7224221
--- /dev/null
+++ b/com/aelitis/azureus/core/devices/DeviceOfflineDownloaderListener.java
@@ -0,0 +1,39 @@
+/*
+ * Created on Sep 1, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.devices;
+
+public interface 
+DeviceOfflineDownloaderListener 
+{
+	public void
+	downloadAdded(
+		DeviceOfflineDownload	download );
+	
+	public void
+	downloadChanged(
+		DeviceOfflineDownload	download );
+	
+	public void
+	downloadRemoved(
+		DeviceOfflineDownload	download );
+	
+}
diff --git a/com/aelitis/azureus/core/devices/DeviceOfflineDownloaderManager.java b/com/aelitis/azureus/core/devices/DeviceOfflineDownloaderManager.java
new file mode 100644
index 0000000..8673aa7
--- /dev/null
+++ b/com/aelitis/azureus/core/devices/DeviceOfflineDownloaderManager.java
@@ -0,0 +1,61 @@
+/*
+ * Created on Sep 1, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.devices;
+
+import org.gudy.azureus2.plugins.download.Download;
+
+public interface 
+DeviceOfflineDownloaderManager 
+{
+	public boolean
+	isOfflineDownloadingEnabled();
+	
+	public void
+	setOfflineDownloadingEnabled(
+		boolean		enabled );
+
+	public boolean
+	getOfflineDownloadingIsAuto();
+	
+	public void
+	setOfflineDownloadingIsAuto(
+		boolean		auto );
+
+	public boolean
+	getOfflineDownloadingIncludePrivate();
+	
+	public void
+	setOfflineDownloadingIncludePrivate(
+		boolean		include );
+	
+	public boolean
+	isManualDownload(
+		Download		download );
+	
+	public void
+	addManualDownloads(
+		Download[]		download );
+
+	public void
+	removeManualDownloads(
+		Download[]		download );
+}
diff --git a/com/aelitis/azureus/core/devices/TranscodeTarget.java b/com/aelitis/azureus/core/devices/TranscodeTarget.java
index 7c245e7..479f625 100644
--- a/com/aelitis/azureus/core/devices/TranscodeTarget.java
+++ b/com/aelitis/azureus/core/devices/TranscodeTarget.java
@@ -79,6 +79,10 @@ TranscodeTarget
 	public boolean
 	isGeneric();
 	
+	public boolean
+	isAudioCompatible(
+		TranscodeFile		file );
+	
 	public void
 	addListener(
 		TranscodeTargetListener		listener );
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceImpl.java
index 4475603..a8f6272 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceImpl.java
@@ -31,6 +31,7 @@ import java.util.*;
 
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.BEncoder;
 import org.gudy.azureus2.core3.util.ByteFormatter;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.DelayedEvent;
@@ -42,6 +43,7 @@ import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 
 import com.aelitis.azureus.core.devices.Device;
+import com.aelitis.azureus.core.devices.DeviceListener;
 import com.aelitis.azureus.core.devices.DeviceMediaRenderer;
 import com.aelitis.azureus.core.devices.TranscodeException;
 import com.aelitis.azureus.core.devices.TranscodeFile;
@@ -112,6 +114,13 @@ DeviceImpl
 
 	protected static final String	PP_TIVO_MACHINE		= "tivo_machine";
 
+	protected static final String	PP_OD_ENABLED			= "od_enabled";
+	protected static final String	PP_OD_SHOWN_FTUX		= "od_shown_ftux";
+	protected static final String	PP_OD_MANUFACTURER		= "od_manufacturer";
+	protected static final String	PP_OD_STATE_CACHE		= "od_state_cache";
+	protected static final String	PP_OD_XFER_CACHE		= "od_xfer_cache";
+	protected static final String	PP_OD_UPNP_DISC_CACHE	= "od_upnp_cache";
+
 	
 	protected static final boolean	PR_AUTO_START_DEFAULT	= true;
 	protected static final boolean	PP_AUTO_COPY_DEFAULT	= false;
@@ -150,6 +159,8 @@ DeviceImpl
 	private Map<Object,String>	errors 	= new HashMap<Object, String>();
 	private Map<Object,String>	infos	= new HashMap<Object, String>();
 	
+	private CopyOnWriteList<DeviceListener>		device_listeners;
+	
 	protected
 	DeviceImpl(
 		DeviceManagerImpl	_manager,
@@ -1012,6 +1023,13 @@ DeviceImpl
 	}
 	
 	public boolean
+	isAudioCompatible(
+		TranscodeFile		file )
+	{
+		return( false );
+	}
+	
+	public boolean
 	getAlwaysCacheFiles()
 	{
 		return( getPersistentBooleanProperty( PP_REND_TRANS_CACHE, false ));
@@ -1298,6 +1316,70 @@ DeviceImpl
 		}
 	}
 	
+	public <T> Map<String,T>
+	getPersistentMapProperty(
+		String					prop,
+		Map<String,T>			def )
+	{
+		synchronized( persistent_properties ){
+			
+			try{
+				Map<String,T>	value = (Map<String,T>)persistent_properties.get( prop );
+		
+				if ( value == null ){
+					
+					return( def );
+				}
+				
+				return( value );
+				
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace(e);
+				
+				return( def );
+			}
+		}
+	}
+	
+	public <T>void
+	setPersistentMapProperty(
+		String					prop,
+		Map<String,T>			value )
+	{
+		boolean	dirty = false;
+		
+		synchronized( persistent_properties ){
+			
+			Map<String,T> existing = getPersistentMapProperty( prop, null );
+			
+			if ( !BEncoder.mapsAreIdentical( value, existing )){
+				
+				try{
+					if ( value == null ){
+						
+						persistent_properties.remove( prop );
+						
+					}else{
+					
+						persistent_properties.put( prop, value );
+					}
+					
+					dirty = true;
+					
+				}catch( Throwable e ){
+					
+					Debug.printStackTrace(e);
+				}
+			}
+		}
+		
+		if ( dirty ){
+			
+			setDirty();
+		}
+	}
+	
 	public void
 	removePersistentProperty(
 		String		prop )
@@ -1891,6 +1973,68 @@ DeviceImpl
 	}
 	
 	protected void
+	fireChanged()
+	{
+		List<DeviceListener> l;
+		
+		synchronized( this ){
+			
+			if ( device_listeners != null ){
+				
+				l = device_listeners.getList();
+				
+			}else{
+				
+				return;
+			}
+		}
+		
+		for ( DeviceListener listener: l ){
+			
+			try{
+				listener.deviceChanged( this );
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+	}
+	
+	public void
+	addListener(
+		DeviceListener		listener )
+	{
+		synchronized( this ){
+			
+			if ( device_listeners == null ){
+				
+				device_listeners = new CopyOnWriteList<DeviceListener>();
+			}
+			
+			device_listeners.add( listener );
+		}
+	}
+	
+	public void
+	removeListener(
+		DeviceListener		listener )
+	{
+		synchronized( this ){
+			
+			if ( device_listeners != null ){
+							
+				device_listeners.remove( listener );
+				
+				if ( device_listeners.size() == 0 ){
+					
+					device_listeners = null;
+				}		
+			}
+		}
+	}
+	
+	protected void
 	log(
 		String		str )
 	{
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceManagerImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceManagerImpl.java
index fa48136..d33f585 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceManagerImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceManagerImpl.java
@@ -44,7 +44,10 @@ import org.gudy.azureus2.core3.util.SimpleTimer;
 import org.gudy.azureus2.core3.util.TimerEvent;
 import org.gudy.azureus2.core3.util.TimerEventPerformer;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.ipc.IPCInterface;
+import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreRunningListener;
@@ -55,15 +58,18 @@ import com.aelitis.azureus.core.messenger.config.PlatformDevicesMessenger;
 
 public class 
 DeviceManagerImpl 
-	implements DeviceManager, AEDiagnosticsEvidenceGenerator
+	implements DeviceManager, DeviceOfflineDownloaderManager, AEDiagnosticsEvidenceGenerator
 {
 	private static final String	LOGGER_NAME 				= "Devices";
 	private static final String	CONFIG_FILE 				= "devices.config";
 	private static final String	AUTO_SEARCH_CONFIG_KEY		= "devices.config.auto_search";
+	
 	private static final String	RSS_ENABLE_CONFIG_KEY		= "devices.config.rss_enable";
-	private static final String	RSS_PORT_CONFIG_KEY			= "devices.config.rss_port";
-	private static final String	RSS_LOCAL_ONLY_CONFIG_KEY	= "devices.config.rss_local_only";
-	private static final int	RSS_PORT_CONFIG__DEFAULT	= 6905;
+	
+	private static final String OD_ENABLED_CONFIG_KEY			= "devices.config.od.enabled";
+	private static final String OD_IS_AUTO_CONFIG_KEY			= "devices.config.od.auto";
+	private static final String OD_INCLUDE_PRIVATE_CONFIG_KEY	= "devices.config.od.inc_priv";
+	
 	
 	private static final String CONFIG_DEFAULT_WORK_DIR	= "devices.config.def_work_dir";
 	
@@ -92,6 +98,9 @@ DeviceManagerImpl
 	}
 	
 	
+	private AzureusCore		azureus_core;
+	
+	private TorrentAttribute			od_manual_ta;
 	
 	private List<DeviceImpl>			device_list = new ArrayList<DeviceImpl>();
 	private Map<String,DeviceImpl>		device_map	= new HashMap<String, DeviceImpl>();
@@ -107,7 +116,7 @@ DeviceManagerImpl
 	private static final int LT_DEVICE_CHANGED		= 2;
 	private static final int LT_DEVICE_ATTENTION	= 3;
 	private static final int LT_DEVICE_REMOVED		= 4;
-	private static final int LT_INITIALIZED		= 5;
+	private static final int LT_INITIALIZED			= 5;
 	
 	private ListenerManager<DeviceManagerListener>	listeners = 
 		ListenerManager.createAsyncManager(
@@ -120,7 +129,7 @@ DeviceManagerImpl
 						int 						type, 
 						Object 						value ) 
 					{
-						Device	device = (Device)value;
+						DeviceImpl	device = (DeviceImpl)value;
 						
 						switch( type ){
 						
@@ -132,13 +141,21 @@ DeviceManagerImpl
 							}
 							case LT_DEVICE_CHANGED:{
 								
-								listener.deviceChanged( device );
+								if ( deviceAdded( device )){
+								
+									device.fireChanged();
+									
+									listener.deviceChanged( device );
+								}
 								
 								break;
 							}
 							case LT_DEVICE_ATTENTION:{
 								
-								listener.deviceAttentionRequest( device );
+								if ( deviceAdded( device )){
+								
+									listener.deviceAttentionRequest( device );
+								}
 								
 								break;
 							}
@@ -156,16 +173,28 @@ DeviceManagerImpl
 							}
 						}
 					}
+					
+					protected boolean
+					deviceAdded(
+						Device		device )
+					{
+						synchronized( DeviceManagerImpl.this ){
+							
+							return( device_list.contains( device ));
+						}
+					}
 				});
 	
 	
 	private boolean	auto_search;
-	private boolean	rss_enable		= false;
-	private boolean	rss_local_only	= true;
-	private int		rss_port		= 0;
 	
 	private DeviceManagerRSSFeed	rss_publisher;
 	
+	private boolean	od_enabled;
+	private boolean	od_is_auto;
+	private boolean od_include_private;
+	
+	
 	private boolean	closing;
 	
 	private boolean	config_unclean;
@@ -199,6 +228,12 @@ DeviceManagerImpl
 	initWithCore(
 		final AzureusCore core ) 
 	{
+		azureus_core = core;
+		
+		od_manual_ta = PluginInitializer.getDefaultInterface().getTorrentManager().getPluginAttribute( "device.manager.od.ta.manual" );
+		
+		rss_publisher = new DeviceManagerRSSFeed( this );
+
 			// need to pick up auto-search early on
 		
 		COConfigurationManager.addAndFireParameterListeners(
@@ -215,6 +250,33 @@ DeviceManagerImpl
 					}
 				});
 		
+		COConfigurationManager.addAndFireParameterListeners(
+				new String[]{
+					OD_ENABLED_CONFIG_KEY,
+					OD_IS_AUTO_CONFIG_KEY,
+					OD_INCLUDE_PRIVATE_CONFIG_KEY
+				},
+				new ParameterListener()
+				{
+					public void 
+					parameterChanged(
+						String name ) 
+					{
+						boolean	new_od_enabled 				= COConfigurationManager.getBooleanParameter( OD_ENABLED_CONFIG_KEY, true );
+						boolean	new_od_is_auto 				= COConfigurationManager.getBooleanParameter( OD_IS_AUTO_CONFIG_KEY, true );
+						boolean	new_od_include_private_priv	= COConfigurationManager.getBooleanParameter( OD_INCLUDE_PRIVATE_CONFIG_KEY, false );
+						
+						if ( new_od_enabled != od_enabled || new_od_is_auto != od_is_auto || new_od_include_private_priv != od_include_private ){
+							
+							od_enabled			= new_od_enabled;
+							od_is_auto			= new_od_is_auto;
+							od_include_private	= new_od_include_private_priv;
+							
+							manageOD();
+						}
+					}
+				});
+		
 			// init tivo before upnp as upnp init completion starts up tivo
 		
 		tivo_manager = new DeviceTivoManager( this );
@@ -229,33 +291,6 @@ DeviceManagerImpl
 		
 		transcode_manager = new TranscodeManagerImpl( this );
 		
-		COConfigurationManager.addAndFireParameterListeners(
-			new String[]{
-				RSS_ENABLE_CONFIG_KEY,
-				RSS_LOCAL_ONLY_CONFIG_KEY,
-				RSS_PORT_CONFIG_KEY
-			},
-			new ParameterListener()
-			{
-				public void 
-				parameterChanged(
-					String name ) 
-				{
-					boolean	new_rss_enable 	= COConfigurationManager.getBooleanParameter( RSS_ENABLE_CONFIG_KEY, false );
-					int		new_rss_port 	= COConfigurationManager.getIntParameter( RSS_PORT_CONFIG_KEY, RSS_PORT_CONFIG__DEFAULT );
-					boolean	new_rss_local 	= COConfigurationManager.getBooleanParameter( RSS_LOCAL_ONLY_CONFIG_KEY, true );
-					
-					if ( new_rss_enable != rss_enable || new_rss_port != rss_port || rss_local_only != new_rss_local ){
-						
-						rss_port		= new_rss_port;
-						rss_enable		= new_rss_enable;
-						rss_local_only	= new_rss_local;
-						
-						manageRSS( core );
-					}
-				}
-			});
-		
 		core.addLifecycleListener(
 			new AzureusCoreLifecycleAdapter()
 			{
@@ -321,39 +356,21 @@ DeviceManagerImpl
 				});
 		
 		initialized = true;
+		
 		listeners.dispatch( LT_INITIALIZED, null );
 	}
 	
 	protected void
-	manageRSS(
-		final AzureusCore		core )
+	manageOD()
 	{
-		synchronized( this ){
+		DeviceImpl[] devices = getDevices();
+		
+		for ( DeviceImpl device: devices ){
 			
-			async_dispatcher.dispatch(
-				new AERunnable()
-				{
-					final boolean	f_enable 	= rss_enable;
-					final int		f_port		= rss_port;
-					final boolean	f_local		= rss_local_only;
-					
-					public void
-					runSupport()
-					{
-						synchronized( DeviceManagerImpl.this ){
-														
-							if ( rss_publisher != null ){
-								
-								rss_publisher.destroy();
-							}
-							
-							if ( f_enable ){
-							
-								rss_publisher = new DeviceManagerRSSFeed( DeviceManagerImpl.this, core, f_port, f_local );
-							}
-						}				
-					}
-				});
+			if ( device.getType() == Device.DT_OFFLINE_DOWNLOADER ){
+				
+				((DeviceOfflineDownloaderImpl)device).checkConfig();
+			}
 		}
 	}
 	
@@ -361,6 +378,22 @@ DeviceManagerImpl
 	UPnPManagerStarted()
 	{
 		tivo_manager.startUp();
+		
+		DeviceImpl[] devices = getDevices();
+		
+		for ( DeviceImpl device: devices ){
+			
+			if ( device instanceof DeviceUPnPImpl ){
+				
+				((DeviceUPnPImpl)device).UPnPInitialised();
+			}
+		}
+	}
+	
+	protected AzureusCore
+	getAzureusCore()
+	{
+		return( azureus_core );
 	}
 	
 	protected DeviceManagerUPnPImpl 
@@ -369,6 +402,19 @@ DeviceManagerImpl
 		return( upnp_manager );
 	}
 	
+	public boolean
+	isTiVoEnabled()
+	{
+		return( tivo_manager.isEnabled());
+	}
+	
+	public void
+	setTiVoEnabled(
+		boolean	enabled )
+	{
+		tivo_manager.setEnabled( enabled );
+	}
+	
 	public DeviceTemplate[] 
 	getDeviceTemplates(
 		int		device_type )
@@ -730,7 +776,7 @@ DeviceManagerImpl
 	public boolean
 	isRSSPublishEnabled()
 	{
-		return( rss_enable );
+		return( COConfigurationManager.getBooleanParameter( RSS_ENABLE_CONFIG_KEY, false ) );
 	}
 	
 	public void
@@ -739,33 +785,93 @@ DeviceManagerImpl
 	{
 		COConfigurationManager.setParameter( RSS_ENABLE_CONFIG_KEY, enabled );
 	}
+	
+	public String
+	getRSSLink()
+	{
+		return( rss_publisher.getFeedURL());
+	}
+	
+		// offline downloader stuff
+	
+	public DeviceOfflineDownloaderManager
+	getOfflineDownlaoderManager()
+	{
+		return( this );
+	}
+	
+	public boolean
+	isOfflineDownloadingEnabled()
+	{
+		return( od_enabled );
+	}
+	
+	public void
+	setOfflineDownloadingEnabled(
+		boolean		enabled )
+	{
+		COConfigurationManager.setParameter( OD_ENABLED_CONFIG_KEY, enabled );
+	}
 
 	public boolean
-	isRSSLocalOnly()
+	getOfflineDownloadingIsAuto()
 	{
-		return( rss_local_only );
+		return( od_is_auto );
 	}
 	
 	public void
-	setRSSLocalOnly(
-		boolean		local_only )
+	setOfflineDownloadingIsAuto(
+		boolean		auto )
 	{
-		COConfigurationManager.setParameter( RSS_LOCAL_ONLY_CONFIG_KEY, local_only );
+		COConfigurationManager.setParameter( OD_IS_AUTO_CONFIG_KEY, auto );
+	}
+
+	public boolean
+	getOfflineDownloadingIncludePrivate()
+	{
+		return( od_include_private );	
 	}
 	
-	public int
-	getRSSPort()
+	public void
+	setOfflineDownloadingIncludePrivate(
+		boolean		include )
 	{
-		return( rss_port );
+		COConfigurationManager.setParameter( OD_INCLUDE_PRIVATE_CONFIG_KEY, include );
 	}
 	
+	public boolean
+	isManualDownload(
+		Download		download )
+	{
+		return( download.getBooleanAttribute( od_manual_ta ));
+	}
+	
+	public void
+	addManualDownloads(
+		Download[]		downloads )
+	{
+		for ( Download d: downloads ){
+			
+			d.setBooleanAttribute( od_manual_ta, true );
+		}
+		
+		manageOD();
+	}
+
 	public void
-	setRSSPort(
-		int		port )
+	removeManualDownloads(
+		Download[]		downloads )
 	{
-		COConfigurationManager.setParameter( RSS_PORT_CONFIG_KEY, port );
+		for ( Download d: downloads ){
+			
+			d.setBooleanAttribute( od_manual_ta, false );
+		}
+		
+		manageOD();
 	}
 	
+		// sdsd
+	
 	protected boolean
 	isExplicitSearch()
 	{
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceManagerRSSFeed.java b/com/aelitis/azureus/core/devices/impl/DeviceManagerRSSFeed.java
index 117fab9..d2f63e9 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceManagerRSSFeed.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceManagerRSSFeed.java
@@ -25,7 +25,6 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.URL;
 import java.net.URLDecoder;
@@ -41,79 +40,48 @@ import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.TimeFormatter;
+import org.gudy.azureus2.core3.util.UrlUtils;
 import org.gudy.azureus2.core3.xml.util.XUXmlWriter;
 
-import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.torrent.Torrent;
-import org.gudy.azureus2.plugins.tracker.Tracker;
-import org.gudy.azureus2.plugins.tracker.web.TrackerWebContext;
-import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageGenerator;
 import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageRequest;
 import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageResponse;
 
-import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.devices.Device;
+import com.aelitis.azureus.core.rssgen.RSSGeneratorPlugin;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 
 public class 
 DeviceManagerRSSFeed 
-	implements TrackerWebPageGenerator
+	implements RSSGeneratorPlugin.Provider
 {
-	private DeviceManagerImpl		manager;
-	private int						port;
+	private static final String PROVIDER = "devices";
 	
-	private PluginInterface			plugin_interface;
-	private TrackerWebContext		context;
+	private DeviceManagerImpl		manager;
+		
+	private RSSGeneratorPlugin		generator;
 	
 	protected
 	DeviceManagerRSSFeed(
-		DeviceManagerImpl	_manager,
-		AzureusCore			_core,
-		int					_port,
-		boolean				_local_only )
+		DeviceManagerImpl	_manager )
 	{
-		manager = _manager;
-		port	= _port;
+		manager 	= _manager;
+		generator	= RSSGeneratorPlugin.getSingleton();
 		
-		plugin_interface = _core.getPluginManager().getDefaultPluginInterface();
+		generator.registerProvider( PROVIDER, this );
+	}
 		
-		try{
-			if ( _local_only ){
-				
-				context = 
-					plugin_interface.getTracker().createWebContext(
-						"DeviceFeed", 
-						_port, 
-						Tracker.PR_HTTP, 
-						InetAddress.getByName( "127.0.0.1" ));
-				
-			}else{
-				
-				context = 
-					plugin_interface.getTracker().createWebContext(
-						"DeviceFeed", 
-						_port, 
-						Tracker.PR_HTTP );
-			}
-			
-			context.addPageGenerator( this );
-			
-			manager.log( "RSS feed initialised on port " + _port );
-			
-		}catch( Throwable e ){
-			
-			manager.log( "Failed to initialise RSS feed on port " + _port, e );
-		}
+	public boolean
+	isEnabled()
+	{
+		return( manager.isRSSPublishEnabled());
 	}
 	
-	protected void
-	destroy()
+	public String
+	getFeedURL()
 	{
-		if ( context != null ){
-			
-			context.destroy();
-		}
+		return( generator.getURL() + PROVIDER );
 	}
 	
 	public boolean
@@ -130,14 +98,12 @@ DeviceManagerRSSFeed
 			return( false );
 		}
 		
-		String	host = local_address.getAddress().getHostAddress();
-		
-		String	feed_url = "http://" + host + ":" + port + request.getURL();
-		
 		URL	url	= request.getAbsoluteURL();
-			
+					
 		String path = url.getPath();
 		
+		path = path.substring( PROVIDER.length()+1);
+		
 		DeviceImpl[] devices = manager.getDevices();
 		
 		OutputStream os = response.getOutputStream();
@@ -148,7 +114,7 @@ DeviceManagerRSSFeed
 			
 			response.setContentType( "text/html; charset=UTF-8" );
 			
-			pw.println( "<HTML><HEAD><TITLE>Vuze device feeds</TITLE></HEAD><BODY>" );
+			pw.println( "<HTML><HEAD><TITLE>Vuze Device Feeds</TITLE></HEAD><BODY>" );
 			
 			for ( DeviceImpl d: devices ){
 			
@@ -159,7 +125,7 @@ DeviceManagerRSSFeed
 
 				String	name = d.getName();
 								
-				pw.println( "<UL><A href=\"/" + URLEncoder.encode( name, "UTF-8" ) + "\">" + name + "</A></UL>" );
+				pw.println( "<LI><A href=\"" + PROVIDER + "/" + URLEncoder.encode( name, "UTF-8" ) + "\">" + name + "</A></LI>" );
 			}
 			
 			pw.println( "</BODY></HTML>" );
@@ -187,6 +153,24 @@ DeviceManagerRSSFeed
 				return( true );
 			}
 			
+			URL	feed_url = url;
+
+				// absolute url is borked as it doesn't set the host properly. hack 
+			
+			String	host = (String)request.getHeaders().get( "host" );
+			
+			if ( host != null ){
+				
+				int	pos = host.indexOf( ':' );
+				
+				if ( pos != -1 ){
+					
+					host = host.substring( 0, pos );
+				}
+				
+				feed_url = UrlUtils.setHost( url, host );
+			}
+			
 			if ( device instanceof DeviceMediaRendererImpl ){
 				
 				((DeviceMediaRendererImpl)device).browseReceived();
@@ -205,13 +189,13 @@ DeviceManagerRSSFeed
 			
 			pw.println( "<channel>" );
 			
-			String channel_title = "Vuze: " + escape( device.getName());
+			String channel_title = "Vuze Device: " + escape( device.getName());
 					
 			pw.println( "<title>" + channel_title + "</title>" );
 			pw.println( "<link>http://vuze.com</link>" );
-			pw.println( "<atom:link href=\"" + feed_url + "\" rel=\"self\" type=\"application/rss+xml\" />" );
+			pw.println( "<atom:link href=\"" + feed_url.toExternalForm() + "\" rel=\"self\" type=\"application/rss+xml\" />" );
 			
-			pw.println( "<description>Vuze RSS Feed for " + escape( device.getName()) + "</description>" );
+			pw.println( "<description>Vuze RSS Feed for device " + escape( device.getName()) + "</description>" );
 			
 			pw.println("<itunes:image href=\"http://www.vuze.com/img/vuze_icon_128.png\"/>");
 			pw.println("<image><url>http://www.vuze.com/img/vuze_icon_128.png</url><title>" + channel_title + "</title><link>http://vuze.com</link></image>");
@@ -292,7 +276,7 @@ DeviceManagerRSSFeed
 	  				
 	  				String mediaContent = "";
 	  				
-	  				URL stream_url = file.getStreamURL( host );
+	  				URL stream_url = file.getStreamURL( feed_url.getHost() );
 	  				
 	  				if ( stream_url != null ){
 	  					
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceManagerUPnPImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceManagerUPnPImpl.java
index 40bf23c..daaca3a 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceManagerUPnPImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceManagerUPnPImpl.java
@@ -57,12 +57,13 @@ import com.aelitis.net.upnp.UPnPListener;
 import com.aelitis.net.upnp.UPnPRootDevice;
 import com.aelitis.net.upnp.UPnPRootDeviceListener;
 import com.aelitis.net.upnp.UPnPService;
+import com.aelitis.net.upnp.services.UPnPOfflineDownloader;
 import com.aelitis.net.upnp.services.UPnPWANConnection;
 
 public class 
 DeviceManagerUPnPImpl 
 {
-	private final static Object KEY_LISTENER_ADDED = new Object();
+	private final static Object KEY_ROOT_DEVICE = new Object();
 	
 	private DeviceManagerImpl		manager;
 	private PluginInterface			plugin_interface;
@@ -481,6 +482,19 @@ DeviceManagerUPnPImpl
 		}
 	}
 	
+	protected void
+	injectDiscoveryCache(
+		Map		cache )
+	{
+		try{
+			upnp.injectDiscoveryCache( cache );
+			
+		}catch( Throwable e ){
+	
+			Debug.out( e );
+		}
+	}
+	
 	public UnassociatedDevice[]
 	getUnassociatedDevices()
 	{
@@ -539,6 +553,12 @@ DeviceManagerUPnPImpl
 		return( result.toArray( new UnassociatedDevice[result.size()]));
 	}
 	
+	public PluginInterface
+	getPluginInterface()
+	{
+		return( plugin_interface );
+	}
+	
 	protected IPCInterface
 	getUPnPAVIPC()
 	{
@@ -645,6 +665,8 @@ DeviceManagerUPnPImpl
 				uid = UUIDGenerator.generateUUIDString();
 				
 				COConfigurationManager.setParameter( "devices.upnp.uid." + unique_name, uid );
+				
+				COConfigurationManager.save();
 			}
 		}
 		
@@ -698,6 +720,45 @@ DeviceManagerUPnPImpl
 			}else if ( service_type.equals( "urn:schemas-upnp-org:service:ContentDirectory:1" )){
 				
 				new_devices.add( new DeviceContentDirectoryImpl( manager, device, service ));
+				
+			}else if ( service_type.equals( "urn:schemas-upnp-org:service:VuzeOfflineDownloaderService:1" )){
+				
+					// ignore local offline downloader
+				
+				try{
+					PluginInterface od_pi = plugin_interface.getPluginManager().getPluginInterfaceByID( "azofflinedownloader" );
+	
+					if ( od_pi != null ){
+					
+						String	local_usn = (String)od_pi.getIPC().invoke( "getUSN", new Object[0] );
+					
+						String	od_usn = device.getRootDevice().getUSN();
+						
+							// we end up with "::upnp:rootdevice" on the end of this - remove
+						
+						int	pos = od_usn.indexOf( "::upnp:rootdevice" );
+						
+						if ( pos > 0 ){
+							
+							od_usn = od_usn.substring( 0, pos );
+						}
+						
+						if ( od_usn.equals( local_usn )){
+							
+							continue;
+						}
+					}
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+				}
+				
+				UPnPOfflineDownloader downloader = (UPnPOfflineDownloader)service.getSpecificService();
+
+				if ( downloader != null ){
+					
+					new_devices.add( new DeviceOfflineDownloaderImpl( manager, device, downloader ));
+				}
 			}
 		}
 		
@@ -712,22 +773,32 @@ DeviceManagerUPnPImpl
 		}
 		
 		for ( final DeviceUPnPImpl new_device: new_devices ){
+				
+			final DeviceImpl actual_device;
 			
-			if ( !update_if_found &&  manager.getDevice( new_device.getID()) != null ){
+			DeviceImpl existing = manager.getDevice( new_device.getID());
+			
+			if ( !update_if_found && existing != null ){
 					
-				continue;
+				actual_device = existing;
+				
+			}else{
+			
+					// grab the actual device as the 'addDevice' call will update an existing one
+					// with same id
+			
+				actual_device = manager.addDevice( new_device );
 			}
 			
-				// grab the actual device as the 'addDevice' call will update an existing one
-				// with same id
+			UPnPRootDevice current_root = device.getRootDevice();
 			
-			final DeviceImpl actual_device = manager.addDevice( new_device );
-
-			if ( actual_device.getTransientProperty( KEY_LISTENER_ADDED ) == null ){
+			UPnPRootDevice existing_root = (UPnPRootDevice)actual_device.getTransientProperty( KEY_ROOT_DEVICE );
+			
+			if ( current_root != existing_root ){
 				
-				actual_device.setTransientProperty( KEY_LISTENER_ADDED, "" );
+				actual_device.setTransientProperty( KEY_ROOT_DEVICE, current_root );
 				
-				device.getRootDevice().addListener(
+				current_root.addListener(
 					new UPnPRootDeviceListener()
 					{
 						public void
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererManual.java b/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererManual.java
index f11469e..462d8e8 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererManual.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererManual.java
@@ -261,6 +261,35 @@ DeviceMediaRendererManual
 		}
 	}
 	
+	public boolean
+	isAudioCompatible(
+		TranscodeFile		transcode_file )
+	{
+		if ( getDeviceClassification().equals( "sony.PSP" )){
+			
+			try{
+				File file = transcode_file.getSourceFile().getFile();
+				
+				if ( file.exists()){
+					
+					String name = file.getName().toLowerCase();
+					
+					if ( name.endsWith( ".mp3" ) || name.endsWith( ".wma" )){
+						
+						((TranscodeFileImpl)transcode_file).setCopyToFolderOverride( ".." + File.separator + "MUSIC" );
+						
+						return( true );
+					}
+				}
+			}catch( Throwable e ){
+				
+				log( "audio compatible check failed", e );
+			}
+		}
+		
+		return( false );
+	}
+	
 	protected void
 	performCopy()
 	{
@@ -448,6 +477,18 @@ DeviceMediaRendererManual
 						
 						File	target = new File( copy_to, file.getName());
 						
+						String override_str = transcode_file.getCopyToFolderOverride();
+						
+						if ( override_str != null ){
+							
+							File override_dir = new File( copy_to, override_str );
+											
+							if ( override_dir.exists()){
+														
+								target = new File( override_dir, file.getName());
+							}
+						}					
+						
 						try{							
 							FileUtil.copyFileWithException( file, target );
 																						
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceOfflineDownloaderImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceOfflineDownloaderImpl.java
new file mode 100644
index 0000000..da569e9
--- /dev/null
+++ b/com/aelitis/azureus/core/devices/impl/DeviceOfflineDownloaderImpl.java
@@ -0,0 +1,1678 @@
+/*
+ * Created on Jan 28, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.devices.impl;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+
+import org.gudy.azureus2.core3.disk.DiskManager;
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.core3.disk.DiskManagerPiece;
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.global.GlobalManager;
+import org.gudy.azureus2.core3.global.GlobalManagerAdapter;
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.peer.PEPeer;
+import org.gudy.azureus2.core3.peer.PEPeerManager;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLSet;
+import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.AESemaphore;
+import org.gudy.azureus2.core3.util.AsyncDispatcher;
+import org.gudy.azureus2.core3.util.BEncoder;
+import org.gudy.azureus2.core3.util.ByteFormatter;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.core3.util.FrequencyLimitedDispatcher;
+import org.gudy.azureus2.core3.util.LightHashMap;
+import org.gudy.azureus2.core3.util.SimpleTimer;
+import org.gudy.azureus2.core3.util.SystemTime;
+import org.gudy.azureus2.core3.util.TimerEventPerformer;
+import org.gudy.azureus2.core3.util.TorrentUtils;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.peers.Peer;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.devices.*;
+import com.aelitis.azureus.core.security.CryptoManagerFactory;
+import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
+import com.aelitis.azureus.core.util.CopyOnWriteList;
+import com.aelitis.azureus.util.DownloadUtils;
+import com.aelitis.net.upnp.UPnPDevice;
+import com.aelitis.net.upnp.UPnPRootDevice;
+import com.aelitis.net.upnp.services.UPnPOfflineDownloader;
+
+public class 
+DeviceOfflineDownloaderImpl
+	extends DeviceUPnPImpl
+	implements DeviceOfflineDownloader
+{
+	public static final int	UPDATE_MILLIS	= 30*1000;
+	public static final int UPDATE_TICKS	= UPDATE_MILLIS/DeviceManagerImpl.DEVICE_UPDATE_PERIOD;
+	
+	public static final int	UPDATE_SPACE_MILLIS	= 3*60*1000;
+	public static final int UPDATE_SPACE_TICKS	= UPDATE_SPACE_MILLIS/DeviceManagerImpl.DEVICE_UPDATE_PERIOD;
+	
+	public static final String	client_id = ByteFormatter.encodeString( CryptoManagerFactory.getSingleton().getSecureID());
+	
+	private static final Object	ERROR_KEY_OD = new Object();
+
+	private volatile UPnPOfflineDownloader		service;
+	private volatile String						service_ip;
+	private volatile String						manufacturer;
+	
+	private long	start_time = SystemTime.getMonotonousTime();
+	
+	private volatile boolean		update_space_outstanding 	= true;
+	private volatile long			space_on_device				= -1;
+	
+	private volatile boolean					closing;
+	
+	private AsyncDispatcher	dispatcher = new AsyncDispatcher();
+	
+	final FrequencyLimitedDispatcher	freq_lim_updater = 
+		new FrequencyLimitedDispatcher(
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					updateDownloads();
+				}
+			},
+			5*1000 );
+	
+	private boolean								start_of_day	= true;
+	private int									consec_errors	= 0;
+	private int									consec_success	= 0;
+	
+	private Map<String,OfflineDownload>			offline_downloads	= new HashMap<String, OfflineDownload>(); 
+	private Map<String,TransferableDownload>	transferable 		= new LinkedHashMap<String,TransferableDownload>();
+	private TransferableDownload				current_transfer;
+	private boolean								is_transferring;
+	
+	
+	private CopyOnWriteList<DeviceOfflineDownloaderListener>	listeners = new CopyOnWriteList<DeviceOfflineDownloaderListener>();		
+	
+	protected
+	DeviceOfflineDownloaderImpl(
+		DeviceManagerImpl			_manager,
+		UPnPDevice					_device,
+		UPnPOfflineDownloader		_service )
+	{
+		super( _manager, _device, Device.DT_OFFLINE_DOWNLOADER );
+		
+		setService( _service );
+	}
+	
+	protected
+	DeviceOfflineDownloaderImpl(
+		DeviceManagerImpl	_manager,
+		Map					_map )
+	
+		throws IOException
+	{
+		super(_manager, _map );
+		
+		manufacturer = getPersistentStringProperty( PP_OD_MANUFACTURER, "?" );
+	}
+	
+	protected boolean
+	updateFrom(
+		DeviceImpl		_other,
+		boolean			_is_alive )
+	{
+		if ( !super.updateFrom( _other, _is_alive )){
+			
+			return( false );
+		}
+		
+		if ( !( _other instanceof DeviceOfflineDownloaderImpl )){
+			
+			Debug.out( "Inconsistent" );
+			
+			return( false );
+		}
+		
+		DeviceOfflineDownloaderImpl other = (DeviceOfflineDownloaderImpl)_other;
+			
+		if ( service == null && other.service != null ){
+			
+			setService( other.service );
+			
+			updateDownloads();
+		}
+		
+		return( true );
+	}
+	
+	protected void
+	setService(
+		UPnPOfflineDownloader	_service )
+	{
+		service	= _service;
+		
+		UPnPRootDevice root = service.getGenericService().getDevice().getRootDevice();
+		
+		service_ip = root.getLocation().getHost();
+		
+		try{
+			service_ip = InetAddress.getByName( service_ip ).getHostAddress();
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+		
+		Map cache = root.getDiscoveryCache();
+		
+		if ( cache != null ){
+			
+			setPersistentMapProperty( PP_OD_UPNP_DISC_CACHE, cache );
+		}
+		
+		manufacturer = root.getDevice().getManufacturer();
+		
+		setPersistentStringProperty( PP_OD_MANUFACTURER, manufacturer );
+		
+		updateDownloads();
+	}
+	
+	protected void 
+	UPnPInitialised() 
+	{
+		super.UPnPInitialised();
+		
+		if ( service == null ){
+		
+			Map	cache = getPersistentMapProperty( PP_OD_UPNP_DISC_CACHE, null );
+		
+			if ( cache != null ){
+			
+				getUPnPDeviceManager().injectDiscoveryCache( cache );
+			}
+		}
+	}
+	
+	protected void 
+	updateStatus(
+		int tick_count ) 
+	{
+		super.updateStatus( tick_count );
+		
+		update_space_outstanding |= tick_count % UPDATE_SPACE_TICKS == 0;
+
+		if ( tick_count % UPDATE_TICKS == 0 ){
+							
+			updateDownloads();
+		}
+	}
+	
+	protected void
+	checkConfig()
+	{
+		freq_lim_updater.dispatch();
+	}
+	
+	protected void
+	updateDownloads()
+	{
+		dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					if ( dispatcher.getQueueSize() == 0 ){
+					
+						updateDownloadsSupport();
+					}
+				}
+			});
+	}
+	
+	protected void
+	updateDownloadsSupport()
+	{
+		AzureusCore core = getManager().getAzureusCore();
+		
+		if ( core == null || closing ){
+			
+				// not yet initialised or closing
+			
+			return;
+		}
+
+		boolean warn_if_dead = SystemTime.getMonotonousTime() - start_time > 3*60*1000;
+		
+		if ( !isAlive() || service == null  ){
+			
+				// no usable service
+			
+			if ( warn_if_dead ){
+			
+				setError( ERROR_KEY_OD, MessageText.getString( "device.od.error.notfound" ));
+			}
+			
+			return;
+		}
+
+		String	error_status = null;
+		
+		Map<String,DownloadManager>			new_offline_downloads 	= new HashMap<String,DownloadManager>();
+		Map<String,TransferableDownload>	new_transferables 		= new HashMap<String,TransferableDownload>();
+		
+		try{	
+			if ( update_space_outstanding ){
+			
+				try{
+					space_on_device = service.getFreeSpace( client_id );
+					
+					update_space_outstanding = false;
+					
+					if ( space_on_device == 0 ){
+						
+						error_status = MessageText.getString( "device.od.error.nospace" );
+					}
+				}catch( Throwable e ){
+					
+					error_status = MessageText.getString( "device.od.error.opfailexcep", new String[]{ "GetFreeSpace", Debug.getNestedExceptionMessage( e )});
+
+					log( "Failed to get free space", e );
+
+				}
+			}
+			
+			Map<String,byte[]>	old_cache 	= (Map<String,byte[]>)getPersistentMapProperty( PP_OD_STATE_CACHE, new HashMap<String,byte[]>());
+			
+			Map<String,byte[]>	new_cache 	= new HashMap<String, byte[]>();
+			
+			GlobalManager gm = core.getGlobalManager();
+			
+			if ( start_of_day ){
+				
+				start_of_day = false;
+				
+				Map<String,Map> xfer_cache = getPersistentMapProperty( PP_OD_XFER_CACHE, new HashMap<String,Map>());
+				
+				if ( xfer_cache.size() > 0 ){
+					
+					List<DownloadManager> initial_downloads = gm.getDownloadManagers();
+					
+					for ( DownloadManager download: initial_downloads ){
+	
+						if ( download.isForceStart()){
+							
+							TOTorrent torrent = download.getTorrent();
+							
+							if ( torrent == null ){
+								
+								continue;
+							}
+							
+							try{
+								byte[] hash = torrent.getHash();
+								
+								String	hash_str = ByteFormatter.encodeString( hash );
+								
+								Map m = xfer_cache.get( hash_str );
+									
+								if ( m != null ){
+									
+									if ( m.containsKey( "f" )){
+										
+										log( download, "Resetting force-start" );
+										
+										download.setForceStart( false );
+									}
+								}
+							}catch( Throwable e ){
+								
+								Debug.printStackTrace(e);
+							}
+						}
+					}
+				}
+				
+				gm.addListener(
+					new GlobalManagerAdapter()
+					{
+						public void
+						downloadManagerAdded(
+							DownloadManager	dm )
+						{
+							freq_lim_updater.dispatch();
+						}
+							
+						public void
+						downloadManagerRemoved( 
+							DownloadManager	dm )
+						{
+							freq_lim_updater.dispatch();
+						}
+					},
+					false );
+			}
+			
+			DeviceManager manager = getManager();
+				
+			DeviceOfflineDownloaderManager dodm = manager.getOfflineDownlaoderManager();
+			
+			List<DownloadManager> downloads;
+			
+			if ( dodm.isOfflineDownloadingEnabled() && isEnabled()){
+
+				List<DownloadManager> initial_downloads = gm.getDownloadManagers();
+
+				List<DownloadManager> relevant_downloads = new ArrayList<DownloadManager>( initial_downloads.size());
+			
+					// remove uninteresting ones
+				
+				for ( DownloadManager download: initial_downloads ){
+				
+					int	state = download.getState();
+										
+					if ( state == DownloadManager.STATE_SEEDING ){
+							// state == DownloadManager.STATE_ERROR ){	removed - might be out of disk space and fixable
+						
+						continue;
+					}
+					
+						// don't include 'stopping' here as we go through stopping on way to queued
+
+					if ( state == DownloadManager.STATE_STOPPED ){
+						
+							// don't remove from downloader if simply paused
+						
+						if ( !download.isPaused()){
+														
+							continue;
+						}
+					}
+					
+						// if it is complete then of no interest
+					
+					if ( download.isDownloadComplete( false )){
+							
+						continue;
+					}
+					
+					relevant_downloads.add( download );
+				}
+			
+				downloads = new ArrayList<DownloadManager>( relevant_downloads.size());
+			
+				if ( dodm.getOfflineDownloadingIsAuto()){
+					
+					boolean	include_private = dodm.getOfflineDownloadingIncludePrivate();
+					
+					if ( include_private ){
+						
+						downloads.addAll( relevant_downloads );
+						
+					}else{
+						
+						for ( DownloadManager download: relevant_downloads ){
+							
+							TOTorrent torrent = download.getTorrent();
+							
+							if ( !TorrentUtils.isReallyPrivate( torrent )){
+								
+								downloads.add( download );
+							}
+						}
+					}
+				}else{
+					
+						// manual, just use the tagged downloads
+					
+					for ( DownloadManager download: relevant_downloads ){
+
+						if ( dodm.isManualDownload( PluginCoreUtils.wrap( download ))){
+							
+							downloads.add( download );
+						}
+					}
+				}
+			}else{
+				
+				downloads = new ArrayList<DownloadManager>();
+			}
+			
+			Map<DownloadManager,byte[]>	download_map = new HashMap<DownloadManager, byte[]>();
+			
+			for ( DownloadManager download: downloads ){
+											
+				TOTorrent torrent = download.getTorrent();
+	
+				if ( torrent == null ){
+					
+					continue;
+				}
+				
+				try{
+					byte[] hash = torrent.getHash();
+					
+					String	hash_str = ByteFormatter.encodeString( hash );
+					
+					DiskManager disk = download.getDiskManager();
+					
+					if ( disk == null ){
+						
+						byte[] existing = old_cache.get( hash_str );
+						
+						if ( existing != null ){
+							
+							new_cache.put( hash_str, existing );
+							
+							download_map.put( download, existing );
+							
+						}else{
+							
+								// assume not yet started and just use the non-skipped files
+							
+							DiskManagerFileInfo[] files = download.getDiskManagerFileInfo();
+							
+							byte[] needed = new byte[( torrent.getNumberOfPieces() + 7 ) / 8];
+
+							int	hits = 0;
+
+							for ( DiskManagerFileInfo file: files ){
+								
+								if ( file.isSkipped()){
+									
+									continue;
+								}
+								
+								int	first_piece 	= file.getFirstPieceNumber();
+								int	last_piece		= first_piece + file.getNbPieces() - 1;
+																
+								int	needed_pos		= first_piece/8;
+								int	current_byte	= 0;
+																
+								for ( int pos=first_piece;pos<=last_piece;pos++ ){
+									
+									current_byte = current_byte << 1;
+																			
+									current_byte += 1;
+										
+									hits++;
+									
+									if (( pos %8 ) == 7 ){
+										
+										needed[needed_pos++] |= (byte)current_byte;
+										
+										current_byte = 0;
+									}
+								}
+								
+								if ( current_byte != 0 ){
+									
+									needed[needed_pos++] |= (byte)(current_byte << (8 - (last_piece % 8)));
+								}
+							}
+							
+							if ( hits > 0 ){
+									
+								new_cache.put( hash_str, needed );
+									
+								download_map.put( download, needed );
+							}
+						}
+					}else{
+					
+						DiskManagerPiece[] pieces = disk.getPieces();
+						
+						byte[] needed = new byte[( pieces.length + 7 ) / 8];
+						
+						int	needed_pos		= 0;
+						int	current_byte	= 0;
+						int	pos 			= 0;
+						
+						int	hits = 0;
+						
+						for ( DiskManagerPiece piece: pieces ){
+							
+							current_byte = current_byte << 1;
+							
+							if ( piece.isNeeded() && !piece.isDone()){
+								
+								current_byte += 1;
+								
+								hits++;
+							}
+							
+							if (( pos %8 ) == 7 ){
+								
+								needed[needed_pos++] = (byte)current_byte;
+								
+								current_byte = 0;
+							}
+							pos++;
+						}
+						
+						if (( pos % 8 ) != 0 ){
+							
+							needed[needed_pos++] = (byte)(current_byte << (8 - (pos % 8)));
+						}
+						
+						if ( hits > 0 ){
+							
+							new_cache.put( hash_str, needed );
+							
+							download_map.put( download, needed );
+						}
+					}
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+				}
+			}
+			
+				// store this so we have consistent record for downloads that queue/pause etc and therefore lose accessible piece details
+			
+			setPersistentMapProperty( PP_OD_STATE_CACHE, new_cache );
+			
+				// sort by download priority
+			
+			List<Map.Entry<DownloadManager, byte[]>> entries = new ArrayList<Map.Entry<DownloadManager,byte[]>>( download_map.entrySet());
+			
+			Collections.sort(
+				entries,
+				new Comparator<Map.Entry<DownloadManager, byte[]>>()
+				{
+					public int 
+					compare(
+						Map.Entry<DownloadManager, byte[]> o1,
+						Map.Entry<DownloadManager, byte[]> o2) 
+					{
+						return( o1.getKey().getPosition() - o2.getKey().getPosition());
+					} 
+				});
+				
+			String	download_hashes = "";
+			
+			Iterator<Map.Entry<DownloadManager, byte[]>> it = entries.iterator();
+			
+			while( it.hasNext()){
+				
+				Map.Entry<DownloadManager, byte[]> entry = it.next();
+				
+				DownloadManager	download = entry.getKey();
+				
+				try{
+					String hash = ByteFormatter.encodeString( download.getTorrent().getHash());
+					
+					download_hashes += ( download_hashes.length()==0?"":"," ) + hash;
+					
+					new_offline_downloads.put( hash, download );
+					
+				}catch( Throwable e ){
+					
+					log( download, "Failed to get download hash", e );
+					
+					it.remove();
+				}
+			}
+			
+			try{
+				String[] set_dl_results = service.setDownloads( client_id, download_hashes );
+				
+				String	set_dl_result	= set_dl_results[0].trim();
+				String	set_dl_status 	= set_dl_results[1];
+				
+				if ( !set_dl_status.equals( "OK" )){
+					
+					error_status = MessageText.getString( "device.od.error.opfailstatus", new String[]{ "SetDownloads", set_dl_status });
+
+					throw( new Exception( "Failing result returned: " + set_dl_status ));
+				}
+				
+				String[]	bits = set_dl_result.split( "," );
+				
+				int	num_bits = set_dl_result.length()==0?0:bits.length;
+				
+				if ( num_bits != entries.size()){
+					
+					log( "SetDownloads returned an invalid number of results (hashes=" + new_offline_downloads.size() + ",result=" + set_dl_result + ")");
+					
+				}else{
+					
+					it = entries.iterator();
+					
+					int	pos = 0;
+					
+					while( it.hasNext()){
+						
+						Map.Entry<DownloadManager, byte[]> entry = it.next();
+						
+						DownloadManager	download = entry.getKey();
+						
+						try{
+							TOTorrent torrent = download.getTorrent();
+	
+							String hash_str = ByteFormatter.encodeString( torrent.getHash());
+							
+							int	status = Integer.parseInt( bits[ pos++ ]);
+		
+							boolean	do_update = false;
+						
+							if ( status == 0 ){
+							
+								do_update = true;
+							
+							}else if ( status == 1 ){
+							
+									// need to add the torrent
+							
+								try{
+										// for vuze content add in the azid
+									
+									if ( PlatformTorrentUtils.isContent( torrent, true )){
+										
+										String ext = DownloadUtils.getTrackerExtensions( PluginCoreUtils.wrap( download ));
+										
+										if ( ext != null && ext.length() > 0 ){
+											
+											try{
+												
+												if ( ext.startsWith( "&" )){
+													
+													ext = ext.substring(1);
+												}
+											
+												torrent = TOTorrentFactory.deserialiseFromMap( torrent.serialiseToMap());
+												
+												torrent.setAnnounceURL( appendToURL( torrent.getAnnounceURL(), ext ));
+												
+												TOTorrentAnnounceURLSet[] sets = torrent.getAnnounceURLGroup().getAnnounceURLSets();
+												
+												for ( TOTorrentAnnounceURLSet set: sets ){
+													
+													URL[] urls = set.getAnnounceURLs();
+													
+													for (int i=0;i<urls.length;i++){
+														
+														urls[i] = appendToURL( urls[i], ext );
+													}
+												}
+												
+												torrent.getAnnounceURLGroup().setAnnounceURLSets( sets );
+												
+											}catch( Throwable e ){
+												
+												log( "Torrent modification failed", e );
+											}
+										}
+									}
+									
+									String add_result = 
+										service.addDownload( 
+											client_id, 
+											hash_str,
+											ByteFormatter.encodeStringFully( BEncoder.encode( torrent.serialiseToMap())));
+									
+									log( download, "AddDownload succeeded" );
+									
+									if ( add_result.equals( "OK" )){
+										
+										do_update = true;
+										
+									}else{
+										
+										error_status = MessageText.getString( "device.od.error.opfailstatus", new String[]{ "AddDownload", add_result });
+									
+										throw( new Exception( "Failed to add download: " + add_result ));
+									}
+								}catch( Throwable e ){
+									
+										// TODO: prevent continual attempts to add same torrent?
+									
+									error_status = MessageText.getString( "device.od.error.opfailexcep", new String[]{ "AddDownload", Debug.getNestedExceptionMessage( e )});
+
+									log( download, "Failed to add download", e );
+								}
+							}else{
+							
+								error_status = MessageText.getString( "device.od.error.opfailstatus", new String[]{ "SetDownloads", String.valueOf( status )});
+
+								log( download, "SetDownloads: error status returned - " + status );
+							}
+					
+							if ( do_update ){
+					
+								try{
+									byte[]	required_map = entry.getValue();
+									
+									String	required_bitfield = ByteFormatter.encodeStringFully( required_map );
+									
+									String[] update_results = 
+										service.updateDownload( 
+											client_id, 
+											hash_str,
+											required_bitfield );
+										
+									String	have_bitfield	= update_results[0];
+									String	update_status 	= update_results[1];
+									
+									if ( !update_status.equals( "OK" )){
+										
+										error_status = MessageText.getString( "device.od.error.opfailstatus", new String[]{ "UpdateDownload", update_status });
+
+										throw( new Exception( "UpdateDownload: Failing result returned: " + update_status ));
+									}
+												
+									int		useful_piece_count 	= 0;
+									
+									if ( have_bitfield.length() > 0 ){
+										
+										byte[]	have_map = ByteFormatter.decodeString( have_bitfield );
+										
+										if ( have_map.length != required_map.length ){
+											
+											throw( new Exception( "UpdateDownload: Returned bitmap length invalid" ));
+										}
+										
+										for ( int i=0;i<required_map.length;i++){
+											
+											int x = ( required_map[i] & have_map[i] )&0xff;
+											
+											if ( x != 0 ){
+													
+												for (int j=0;j<8;j++){
+													
+													if ((x&0x01) != 0 ){
+														
+														useful_piece_count++;
+													}
+													
+													x >>= 1;
+												}
+											}
+										}
+										
+										if ( useful_piece_count > 0 ) {
+										
+											long	piece_size	= torrent.getPieceLength();
+
+											new_transferables.put( hash_str, new TransferableDownload( download, hash_str, have_map, useful_piece_count * piece_size ));
+										}
+									}
+									
+									if ( useful_piece_count > 0 ){
+									
+										log( download, "They have " + useful_piece_count + " pieces that we don't" );
+									}
+									
+								}catch( Throwable e ){
+							
+									error_status = MessageText.getString( "device.od.error.opfailexcep", new String[]{ "UpdateDownload", Debug.getNestedExceptionMessage( e )});
+
+									log( download, "UpdateDownload failed", e );
+								}
+							}
+						}catch( Throwable e ){
+						
+							log( download, "Processing failed", e );
+						}
+					}
+				}
+				
+			}catch( Throwable e ){
+				
+				error_status = MessageText.getString( "device.od.error.opfailexcep", new String[]{ "SetDownloads", Debug.getNestedExceptionMessage( e )});
+				
+				log( "SetDownloads failed", e );
+			}
+		}finally{
+			
+			updateTransferable( new_transferables );
+			
+			List<OfflineDownload>	new_ods = new ArrayList<OfflineDownload>();
+			List<OfflineDownload>	del_ods = new ArrayList<OfflineDownload>();
+			List<OfflineDownload>	cha_ods = new ArrayList<OfflineDownload>();
+			
+			synchronized( offline_downloads ){
+			
+				for (Map.Entry<String,DownloadManager> entry: new_offline_downloads.entrySet()){
+				
+					String key = entry.getKey();
+					
+					if ( !offline_downloads.containsKey( key )){
+						
+						OfflineDownload new_od = new OfflineDownload( entry.getValue());
+						
+						offline_downloads.put( key, new_od );
+						
+						new_ods.add( new_od );
+					}
+				}
+				
+				Iterator<Map.Entry<String,OfflineDownload>> it = offline_downloads.entrySet().iterator();
+				
+				while( it.hasNext()){
+					
+					Map.Entry<String,OfflineDownload>	entry = it.next();
+					
+					String 			key 	= entry.getKey();
+					OfflineDownload	od		= entry.getValue();
+					
+					if ( new_offline_downloads.containsKey( key )){
+						
+						TransferableDownload new_td = transferable.get( key );
+						
+						TransferableDownload existing_td = od.getTransferable();
+						
+						if ( new_td != existing_td ){
+							
+							if ( !new_ods.contains( od )){
+								
+								cha_ods.add( od );
+							}
+							
+							od.setTransferable( new_td );
+						}
+					}else{
+						
+						it.remove();
+						
+						del_ods.add( od );
+					}
+				}
+			}
+			
+			for ( OfflineDownload od: new_ods ){
+				
+				for ( DeviceOfflineDownloaderListener listener: listeners ){
+					
+					try{
+						listener.downloadAdded( od );
+						
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+					}
+				}
+			}
+			
+			for ( OfflineDownload od: cha_ods ){
+				
+				for ( DeviceOfflineDownloaderListener listener: listeners ){
+					
+					try{
+						listener.downloadChanged( od );
+						
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+					}
+				}
+			}
+			
+			for ( OfflineDownload od: del_ods ){
+				
+				for ( DeviceOfflineDownloaderListener listener: listeners ){
+					
+					try{
+						listener.downloadRemoved( od );
+						
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+					}
+				}
+			}
+			
+			updateError( error_status );
+		}
+	}
+
+	protected void
+	updateError(
+		String	str )
+	{
+		if ( str == null ){
+			
+			setError( ERROR_KEY_OD, null );
+			
+			consec_errors = 0;
+			
+			consec_success++;
+			
+		}else{
+			
+			consec_errors++;
+			
+			consec_success = 0;
+			
+			if ( consec_errors > 2 ){
+				
+				setError( ERROR_KEY_OD, str );
+			}
+		}
+	}
+	
+	protected URL
+	appendToURL(
+		URL			url,
+		String		ext )
+	
+		throws MalformedURLException
+	{
+		String url_str = url.toExternalForm();
+		
+		if ( url_str.indexOf( '?' ) == -1 ){
+			
+			url_str += "?" + ext;
+			
+		}else{
+			
+			url_str += "&" + ext;
+		}
+		
+		return( new URL( url_str ));
+	}
+	
+	protected void
+	updateTransferable(
+		Map<String,TransferableDownload>	map )
+	{
+			// remove non-transferable entries
+		
+		Iterator<Map.Entry<String,TransferableDownload>>	it = transferable.entrySet().iterator();
+		
+		while( it.hasNext()){
+			
+			Map.Entry<String,TransferableDownload> entry = it.next();
+			
+			if ( !map.containsKey( entry.getKey())){
+					
+				TransferableDownload existing = entry.getValue();
+				
+				if ( existing == current_transfer ){
+					
+					current_transfer.deactivate();
+						
+					current_transfer = null;
+				}
+				
+				it.remove();
+			}
+		}
+		
+			// add in new ones
+		
+		for ( TransferableDownload td: map.values()){
+			
+			String hash = td.getHash();
+			
+			if ( !transferable.containsKey( hash )){
+				
+				transferable.put( hash, td );
+			}
+		}
+		
+		if ( transferable.size() == 0 ){
+			
+			if ( is_transferring ){
+			
+				is_transferring = false;
+				
+				setBusy( false );
+			}
+			
+			return;
+		}
+		
+		if ( !is_transferring ){
+		
+			is_transferring = true;
+			
+			setBusy( true );
+		}
+		
+			// check current
+		
+		if ( current_transfer != null && transferable.size() > 0 ){
+			
+				// rotate through them in case something's stuck for whatever reason
+			
+			long	now = SystemTime.getMonotonousTime();
+			
+			long	runtime = now - current_transfer.getStartTime();
+						
+			if ( runtime >= 30*1000 ){
+				
+				boolean	rotate = false;
+
+				PEPeerManager pm = current_transfer.getDownload().getPeerManager();
+				
+				if ( pm == null ){
+					
+					rotate = true;
+					
+				}else{
+					
+					if ( runtime > 3*60*1000 ){
+					
+						List<PEPeer> peers = pm.getPeers( service_ip );
+						
+						if ( peers.size() == 0 ){
+							
+							rotate = true;
+							
+						}else{
+						
+							PEPeer peer = peers.get(0);
+							
+							if ( peer.getStats().getDataReceiveRate() < 1024 ){
+								
+								rotate = true;
+							}
+						}
+					}
+				}
+				
+				if ( rotate ){
+					
+					current_transfer.deactivate();
+					
+					current_transfer = null;
+				}
+			}
+		}
+		
+		if ( current_transfer == null ){
+			
+			Iterator<TransferableDownload> it2 = transferable.values().iterator();
+			
+			current_transfer = it2.next();
+			
+			it2.remove();
+			
+			transferable.put( current_transfer.getHash(), current_transfer );
+		}
+		
+		if ( current_transfer != null ){
+			
+			if ( !current_transfer.isActive()){
+				
+				current_transfer.activate();
+			}
+			
+			if ( current_transfer.isForced()){
+				
+				Map<String,Map> xfer_cache = new HashMap<String,Map>();
+				
+				Map m = new HashMap();
+				
+				m.put( "f", new Long(1));
+				
+				xfer_cache.put( current_transfer.getHash(), m );
+				
+				setPersistentMapProperty( PP_OD_XFER_CACHE, xfer_cache );
+			}
+			
+			DownloadManager	download = current_transfer.getDownload();
+			
+			int	data_port = current_transfer.getDataPort();
+			
+			if ( data_port <= 0 ){
+								
+				try{
+					String[] start_results = service.startDownload( client_id, current_transfer.getHash());
+					
+					String start_status = start_results[1];
+					
+					if ( !start_status.equals( "OK" )){
+						
+						throw( new Exception( "Failing result returned: " + start_status ));
+					}
+					
+					data_port = Integer.parseInt( start_results[0] );
+					
+					log( download, "StartDownload succeeded - data port=" + data_port );
+
+				}catch( Throwable e ){
+					
+					log( download, "StartDownload failed", e );
+				}
+			}
+			
+			if ( data_port > 0 ){
+				
+				current_transfer.setDataPort( data_port );
+			}
+			
+			final TransferableDownload transfer = current_transfer;
+
+			dispatcher.dispatch(
+				new AERunnable()
+				{
+					private final int[]	count = { 0 };
+					
+					public void
+					runSupport()
+					{
+						count[0]++;
+						
+						if ( current_transfer != transfer || !transfer.isActive()){
+							
+							return;
+						}
+						
+						PEPeerManager pm = transfer.getDownload().getPeerManager();
+						
+						if ( pm == null ){
+							
+							return;
+						}
+						
+						List<PEPeer> peers = pm.getPeers( service_ip );
+								
+						if ( peers.size() > 0 ){
+			
+							return;
+						}
+						
+						Map	user_data = new LightHashMap();
+												
+						user_data.put( Peer.PR_PRIORITY_CONNECTION, new Boolean( true ));
+						
+						pm.addPeer( service_ip, transfer.getDataPort(), 0, false, user_data );
+						
+						if ( count[0] < 3 ){
+							
+							final AERunnable target = this;
+							
+							SimpleTimer.addEvent(
+								"OD:retry",
+								SystemTime.getCurrentTime()+5*1000,
+								new TimerEventPerformer()
+								{
+									public void 
+									perform(
+										org.gudy.azureus2.core3.util.TimerEvent event ) 
+									{
+										dispatcher.dispatch( target );
+									};
+								});
+						}
+					}
+				});
+		}
+	}
+	
+	protected void
+	close()
+	{
+		super.close();
+	
+		final AESemaphore sem = new AESemaphore( "DOD:closer" );
+		
+		dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void 
+				runSupport() 
+				{
+					try{
+						closing	= true;
+						
+						if ( service != null ){
+							
+							try{
+								service.activate( client_id );
+								
+							}catch( Throwable e ){
+								
+							}
+						}
+					}finally{
+						
+						sem.release();
+					}
+				}
+			});
+		
+		sem.reserve(250);
+	}
+	
+	public boolean
+	isEnabled()
+	{
+		return( getPersistentBooleanProperty( PP_OD_ENABLED, false ));
+	}
+	
+	public void
+	setEnabled(
+		boolean	b )
+	{
+		setPersistentBooleanProperty( PP_OD_ENABLED, b );
+		
+		if ( b ){
+			
+			freq_lim_updater.dispatch();
+		}
+	}
+
+	public boolean
+	hasShownFTUX()
+	{
+		return( getPersistentBooleanProperty( PP_OD_SHOWN_FTUX, false ));
+	}
+	
+	public void
+	setShownFTUX()
+	{
+		setPersistentBooleanProperty( PP_OD_SHOWN_FTUX, true );
+	}
+	
+	public String
+	getManufacturer()
+	{
+		return( manufacturer );
+	}
+	
+	public long
+	getSpaceAvailable()
+	
+		throws DeviceManagerException
+	{
+		if ( space_on_device >= 0 ){
+			
+			return( space_on_device );
+		}
+		
+		if ( service == null ){
+			
+			throw( new DeviceManagerException( "Device is not online" ));
+		}
+		
+		try{
+			space_on_device = service.getFreeSpace( client_id );
+			
+			update_space_outstanding = false;
+
+			return( space_on_device );
+			
+		}catch( Throwable e ){
+			
+			throw( new DeviceManagerException( "Failed to read available space", e ));
+		}
+	}
+	
+	public int
+	getTransferingCount()
+	{
+		return( transferable.size());
+	}
+	
+	public DeviceOfflineDownload[]
+ 	getDownloads()
+	{
+		synchronized( offline_downloads ){
+			
+			return( offline_downloads.values().toArray( new DeviceOfflineDownload[ offline_downloads.size()]));
+		}
+	}
+ 		
+ 	public void
+ 	addListener(
+ 		DeviceOfflineDownloaderListener		listener )
+ 	{
+ 		listeners.add( listener );
+ 	}
+ 	
+ 	public void
+ 	removeListener(
+ 		DeviceOfflineDownloaderListener		listener )
+ 	{
+ 		listeners.remove( listener );
+ 	}
+	       
+	protected void
+	getDisplayProperties(
+		List<String[]>	dp )
+	{
+		super.getDisplayProperties( dp );
+		
+		String	space_str = "";
+		
+		if ( space_on_device >= 0 ){
+			
+			space_str = DisplayFormatters.formatByteCountToKiBEtc( space_on_device );
+		}
+		
+		addDP( dp, "azbuddy.enabled", isEnabled());
+		addDP( dp, "device.od.space", space_str );
+	}
+	
+	protected void
+	log(
+		DownloadManager		download,	
+		String				str )
+	{
+		log( download.getDisplayName() + ": " + str );
+	}
+	
+	protected void
+	log(
+		DownloadManager		download,	
+		String				str,
+		Throwable			e )
+	{
+		log( download.getDisplayName() + ": " + str, e );
+	}
+	
+	protected void
+	log(
+		String	str )
+	{
+		super.log( "OfflineDownloader: " + str );
+	}
+	
+	protected void
+	log(
+		String		str,
+		Throwable	e )
+	{
+		super.log( "OfflineDownloader: " + str, e );
+	}
+	
+	protected class
+	OfflineDownload
+		implements DeviceOfflineDownload
+	{
+		private DownloadManager		core_download;
+		private Download			download;
+		
+		private TransferableDownload	transferable;
+		
+		protected
+		OfflineDownload(
+			DownloadManager		_core_download )
+		{
+			core_download	= _core_download;
+			download		= PluginCoreUtils.wrap( core_download );
+		}
+		
+		public Download
+		getDownload()
+		{
+			return( download );
+		}
+		
+		public boolean
+		isTransfering()
+		{
+			return( transferable != null );
+		}
+		
+		public long
+		getCurrentTransferSize()
+		{
+			TransferableDownload t = transferable;
+			
+			if ( t == null ){
+				
+				return( 0 );
+			}
+			
+			return( t.getCurrentTransferSize());
+		}
+		
+		public long
+		getRemaining()
+		{
+			TransferableDownload t = transferable;
+			
+			if ( t == null ){
+				
+				return( 0 );
+			}
+			
+			return( t.getRemaining());
+		}
+		
+		protected void
+		setTransferable(
+			TransferableDownload		td )
+		{
+			transferable = td;
+		}
+	
+		protected TransferableDownload
+		getTransferable()
+		{
+			return( transferable );
+		}
+	}
+	
+	protected class
+	TransferableDownload
+	{
+		private DownloadManager		download;
+		private String				hash_str;
+		private byte[]				have_map;
+		
+		private boolean				active;
+		private long				start_time;	
+		private boolean				forced;
+		
+		private int					data_port;
+		
+		private long				transfer_size;
+		
+		private volatile long		last_calc;
+		private volatile long		last_calc_time;
+		
+		protected
+		TransferableDownload(
+			DownloadManager		_download,
+			String				_hash_str,
+			byte[]				_have_map,
+			long				_transfer_size_estimate )
+		{
+			download		= _download;
+			hash_str		= _hash_str;
+			have_map		= _have_map;
+			
+				// not totally accurate, in general will be > required as based purely on piece
+				// size as opposed to blocks. however, we need an initial estimate as the download
+				// may not yet be running and therefore we can't get accurate size now
+			
+			transfer_size 	= _transfer_size_estimate;
+			
+			last_calc		= transfer_size;
+		}
+		
+		protected long
+		calcDiff()
+		{
+			long	now = SystemTime.getMonotonousTime();
+			
+			if ( now - last_calc_time < 2*1000 ){
+				
+				return( last_calc );
+			}
+			
+			DiskManager disk = download.getDiskManager();
+
+			if ( disk == null ){
+				
+				return( last_calc );
+			}
+			
+			DiskManagerPiece[] pieces = disk.getPieces();
+			
+			int	pos		= 0;
+			int	current	= 0;
+			
+			long remaining = 0;
+			
+			for ( int i=0; i<pieces.length; i++ ){
+			
+				if ( i % 8 == 0 ){
+					
+					current = have_map[pos++]&0xff;
+				}
+				
+				if (( current & 0x80 ) != 0 ){
+					
+					DiskManagerPiece piece = pieces[i];
+					
+					boolean[] written = piece.getWritten();
+					
+					if ( written == null ){
+						
+						if ( !piece.isDone()){
+					
+							remaining += piece.getLength();
+						}
+					}else{
+						
+						for (int j=0;j<written.length;j++){
+							
+							if ( !written[j] ){
+								
+								remaining += piece.getBlockSize( j );
+							}
+						}
+					}
+				}
+				
+				current <<= 1;
+			}
+			
+			last_calc		= remaining;
+			last_calc_time 	= now;
+			
+			return( last_calc );
+		}
+		
+		protected long
+		getCurrentTransferSize()
+		{
+			return( transfer_size );
+		}
+		
+		protected long
+		getRemaining()
+		{
+			return( calcDiff());
+		}
+		
+		protected long
+		getStartTime()
+		{
+			return( start_time );
+		}
+		
+		protected boolean
+		isForced()
+		{
+			return( forced );
+		}
+		
+		protected boolean
+		isActive()
+		{
+			return( active );
+		}
+		
+		protected int
+		getDataPort()
+		{
+			return( data_port );
+		}
+		
+		protected void
+		setDataPort(
+			int		dp )
+		{
+			data_port = dp;
+		}
+		
+		protected void
+		activate()
+		{
+			active		= true;		
+			start_time 	= SystemTime.getMonotonousTime();
+			
+			if ( download.isForceStart()){
+
+				log( download, "Activating for transfer" );
+				
+			}else{
+				
+				log( download, "Activating for transfer; setting force-start" );
+
+				forced = true;
+								
+				download.setForceStart( true );
+			}
+		}
+		
+		protected void
+		deactivate()
+		{
+			active = false;
+			
+			if ( forced ){
+
+				log( download, "Deactivating for transfer; resetting force-start" );
+	
+				download.setForceStart( false );
+				
+			}else{
+				
+				log( download, "Deactivating for transfer" );
+			}
+			
+			data_port	= 0;
+		}
+		
+		protected DownloadManager
+		getDownload()
+		{
+			return( download );
+		}
+		
+		protected String
+		getHash()
+		{
+			return( hash_str );
+		}
+		
+		protected byte[]
+		getHaveMap()
+		{
+			return( have_map );
+		}
+	}
+}
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceTivoManager.java b/com/aelitis/azureus/core/devices/impl/DeviceTivoManager.java
index 0696e71..a26a74b 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceTivoManager.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceTivoManager.java
@@ -26,10 +26,12 @@ import java.io.IOException;
 import java.net.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.AESemaphore;
 import org.gudy.azureus2.core3.util.AEThread2;
 import org.gudy.azureus2.core3.util.Base32;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.DelayedEvent;
 import org.gudy.azureus2.core3.util.RandomUtils;
 import org.gudy.azureus2.core3.util.SimpleTimer;
 import org.gudy.azureus2.core3.util.SystemTime;
@@ -58,6 +60,7 @@ DeviceTivoManager
 	private DeviceManagerImpl		device_manager;
 	private PluginInterface 		plugin_interface;
 	
+	private boolean	is_enabled;
 	private String	uid;
 	private String	server_name	= "Vuze";
 	
@@ -77,6 +80,8 @@ DeviceTivoManager
 	{
 		plugin_interface = PluginInitializer.getDefaultInterface();
 
+		is_enabled = COConfigurationManager.getBooleanParameter( "devices.tivo.enabled", true );
+
 		uid = COConfigurationManager.getStringParameter( "devices.tivo.uid", null );
 		
 		if ( uid == null ){
@@ -89,7 +94,7 @@ DeviceTivoManager
 			
 			COConfigurationManager.setParameter( "devices.tivo.uid", uid );
 		}
-		
+				
 			// set up default server name
 		
 		try{
@@ -124,32 +129,61 @@ DeviceTivoManager
 			
 		if ( found_tivo || device_manager.getAutoSearch()){
 			
-			search( found_tivo );
+			search( found_tivo, false );
+		}
+	}
+	
+	protected boolean
+	isEnabled()
+	{
+		return( is_enabled );
+	}
+	
+	protected void
+	setEnabled(
+		boolean	enabled )
+	{
+		COConfigurationManager.setParameter( "devices.tivo.enabled", enabled );
+		
+		if ( enabled ){
+			
+			search( false, true );
+			
+		}else{
+			
+			for ( Device device: device_manager.getDevices()){
+				
+				if ( device instanceof DeviceTivo ){
+		
+					device.remove();
+				}
+			}
 		}
 	}
 	
 	protected void
 	search()
 	{
-		search( false );
+		search( false, false );
 	}
 	
 	protected void
 	search(
-		boolean	persistent )
+		boolean		persistent,
+		boolean		async )
 	{
 		try{
 			synchronized( this ){
 				
 				if ( current_search == null ){
 					
-					current_search = new Searcher( persistent );
+					current_search = new Searcher( persistent, async );
 					
 				}else{
 					
 					if ( !current_search.wakeup()){
 						
-						current_search = new Searcher( persistent );
+						current_search = new Searcher( persistent, async );
 					}
 				}
 			}
@@ -210,29 +244,32 @@ DeviceTivoManager
 		byte[]		buffer,
 		int			length )
 	{
-		try{
-			Map<String,String>	map = decodeBeacon( buffer, length );
+		if ( is_enabled ){
 			
-			String id = map.get( "identity" );
-			
-			if ( id == null || id.equals( uid )){
+			try{
+				Map<String,String>	map = decodeBeacon( buffer, length );
 				
-				return( false );
-			}
-			
-			String platform = map.get( "platform" );
-			
-			if ( platform != null && platform.toLowerCase().startsWith( "tcd/")){
+				String id = map.get( "identity" );
 				
-				String classification = "tivo." + platform.substring( 4 ).toLowerCase();
+				if ( id == null || id.equals( uid )){
+					
+					return( false );
+				}
+				
+				String platform = map.get( "platform" );
 				
-				foundTiVo( sender, id, classification, (String)map.get( "machine" ));
+				if ( platform != null && platform.toLowerCase().startsWith( "tcd/")){
+					
+					String classification = "tivo." + platform.substring( 4 ).toLowerCase();
+					
+					foundTiVo( sender, id, classification, (String)map.get( "machine" ));
+					
+					return( true );
+				}
+			}catch( Throwable e ){
 				
-				return( true );
+				log( "Failed to decode beacon", e );
 			}
-		}catch( Throwable e ){
-			
-			log( "Failed to decode beacon", e );
 		}
 		
 		return( false );
@@ -328,7 +365,8 @@ DeviceTivoManager
 		
 		protected
 		Searcher(
-			boolean	_persistent )
+			boolean		_persistent,
+			boolean		_async )
 		
 			throws DeviceManagerException
 		{
@@ -373,7 +411,7 @@ DeviceTivoManager
 								id = (String)request.getHeaders().get( "tivo_tcd_id" );	
 							}
 							
-							if ( id != null ){
+							if ( id != null && is_enabled ){
 								
 								persistent = true;
 								
@@ -481,10 +519,25 @@ DeviceTivoManager
 					}
 				}.start();
 					
-				start_sem.reserve( 5000 );
-				
-				sendBeacon();
+				if ( _async ){
+					
+					new DelayedEvent( 
+						"search:delay", 
+						5000,
+						new AERunnable()
+						{
+							public void
+							runSupport()
+							{
+								sendBeacon();
+							}
+						});	
+				}else{
+					
+					start_sem.reserve( 5000 );
 				
+					sendBeacon();
+				}
 
 				log( "Initiated device search" );
 				
@@ -501,14 +554,17 @@ DeviceTivoManager
 		protected void
 		sendBeacon()
 		{
-			try{
-				byte[] 	bytes = encodeBeacon( true, tcp_port );
-				
-				control_socket.send( new DatagramPacket( bytes, bytes.length, InetAddress.getByName( "255.255.255.255" ), CONTROL_PORT ));
-				
-			}catch( Throwable e ){
+			if ( is_enabled ){
 				
-				log( "Failed to send beacon", e );
+				try{
+					byte[] 	bytes = encodeBeacon( true, tcp_port );
+					
+					control_socket.send( new DatagramPacket( bytes, bytes.length, InetAddress.getByName( "255.255.255.255" ), CONTROL_PORT ));
+					
+				}catch( Throwable e ){
+					
+					log( "Failed to send beacon", e );
+				}
 			}
 		}
 		
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceUPnPImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceUPnPImpl.java
index fc6d223..e3cea06 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceUPnPImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceUPnPImpl.java
@@ -227,6 +227,11 @@ DeviceUPnPImpl
 		super.initialise();
 	}
 	
+	protected void
+	UPnPInitialised()
+	{
+	}
+	
 	@Override
 	protected void
 	destroy()
@@ -234,6 +239,12 @@ DeviceUPnPImpl
 		super.destroy();
 	}
 	
+	protected DeviceManagerUPnPImpl
+	getUPnPDeviceManager()
+	{
+		return( upnp_manager );
+	}
+	
 	protected UPnPDevice
 	getUPnPDevice()
 	{
diff --git a/com/aelitis/azureus/core/devices/impl/TranscodeFileImpl.java b/com/aelitis/azureus/core/devices/impl/TranscodeFileImpl.java
index 3057e36..4bed1bd 100644
--- a/com/aelitis/azureus/core/devices/impl/TranscodeFileImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/TranscodeFileImpl.java
@@ -65,6 +65,7 @@ TranscodeFileImpl
 	private static final String			KEY_VIDEO_HEIGHT		= "at_vh";
 	private static final String			KEY_DATE				= "at_dt";
 	private static final String			KEY_CATEGORIES			= PT_CATEGORY;
+	private static final String			KEY_COPY_TO_OVERRIDE	= "ct_over";
 
 	private DeviceImpl					device;
 	private String						key;
@@ -414,6 +415,19 @@ TranscodeFileImpl
 	}
 	
 	protected void
+	setCopyToFolderOverride(
+		String s )
+	{
+		setString( KEY_COPY_TO_OVERRIDE, s );
+	}
+	
+	public String
+	getCopyToFolderOverride()
+	{
+		return( getString( KEY_COPY_TO_OVERRIDE ));
+	}
+	
+	protected void
 	update(
 		TranscodeProviderAnalysis		analysis )
 	{
diff --git a/com/aelitis/azureus/core/devices/impl/TranscodeJobImpl.java b/com/aelitis/azureus/core/devices/impl/TranscodeJobImpl.java
index 05a164d..e6fecdf 100644
--- a/com/aelitis/azureus/core/devices/impl/TranscodeJobImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/TranscodeJobImpl.java
@@ -489,8 +489,9 @@ TranscodeJobImpl
 		// I get the event even if listeners haven't had a chance to be added.
 		// This also ensures only one failed qos gets sent
 		try {
-			int logState = TranscodeJob.ST_FAILED;
-			if ( !isStream() && getAutoRetryCount() == 0 && canUseDirectInput() && !useDirectInput()){
+			int logState = state;
+			if (state != ST_STOPPED && !isStream() && getAutoRetryCount() == 0
+					&& canUseDirectInput() && !useDirectInput()) {
 				// we are going to retry..
 				logState |= 0x100;
 			}
diff --git a/com/aelitis/azureus/core/devices/impl/TranscodeQueueImpl.java b/com/aelitis/azureus/core/devices/impl/TranscodeQueueImpl.java
index 840e3a1..d7bac16 100644
--- a/com/aelitis/azureus/core/devices/impl/TranscodeQueueImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/TranscodeQueueImpl.java
@@ -129,7 +129,9 @@ TranscodeQueueImpl
 		
 		current_job = job;
 		
-		job.getDevice().setTranscoding( true );
+		DeviceImpl	device = job.getDevice();
+		
+		device.setTranscoding( true );
 		
 		try{
 			job.starts();
@@ -252,6 +254,19 @@ TranscodeQueueImpl
 			}else{
 				
 				tt_req = job.getTranscodeRequirement();
+				
+					// audio hack for PSP audio
+				
+				if ( device instanceof TranscodeTarget ){
+					
+					if ( provider_analysis.getLongProperty( TranscodeProviderAnalysis.PT_VIDEO_HEIGHT ) == 0 ){
+						
+						if (((TranscodeTarget)device).isAudioCompatible( transcode_file )){
+					
+							tt_req = TranscodeTarget.TRANSCODE_NEVER;
+						}
+					}
+				}
 			}
 						
 			if ( tt_req == TranscodeTarget.TRANSCODE_NEVER ){
@@ -550,7 +565,7 @@ TranscodeQueueImpl
 					}
 				}else{
 					
-					if ( job.getDevice().getAlwaysCacheFiles()){
+					if ( device.getAlwaysCacheFiles()){
 						
 						PluginInterface av_pi = PluginInitializer.getDefaultInterface().getPluginManager().getPluginInterfaceByID( "azupnpav" );
 						
@@ -735,7 +750,7 @@ TranscodeQueueImpl
 				pipe.destroy();
 			}
 			
-			job.getDevice().setTranscoding( false );
+			device.setTranscoding( false );
 
 			current_job = null;
 		}
diff --git a/com/aelitis/azureus/core/dht/DHT.java b/com/aelitis/azureus/core/dht/DHT.java
index 93802cc..c314480 100644
--- a/com/aelitis/azureus/core/dht/DHT.java
+++ b/com/aelitis/azureus/core/dht/DHT.java
@@ -52,17 +52,21 @@ DHT
 	public static final String	PR_ORIGINAL_REPUBLISH_INTERVAL			= "OriginalRepublishInterval";
 	public static final String	PR_CACHE_REPUBLISH_INTERVAL				= "CacheRepublishInterval";
 
-	public static final byte		FLAG_SINGLE_VALUE	= 0x00;
-	public static final byte		FLAG_DOWNLOADING	= 0x01;
-	public static final byte		FLAG_SEEDING		= 0x02;
-	public static final byte		FLAG_MULTI_VALUE	= 0x04;
-	public static final byte		FLAG_STATS			= 0x08;
-	public static final byte		FLAG_ANON			= 0x10;
-	public static final byte		FLAG_PRECIOUS		= 0x20;
-	public static final byte		FLAG_PUT_AND_FORGET	= 0x40;		// local only
+	public static final byte		FLAG_SINGLE_VALUE		= 0x00;
+	public static final byte		FLAG_DOWNLOADING		= 0x01;
+	public static final byte		FLAG_SEEDING			= 0x02;
+	public static final byte		FLAG_MULTI_VALUE		= 0x04;
+	public static final byte		FLAG_STATS				= 0x08;
+	public static final byte		FLAG_ANON				= 0x10;
+	public static final byte		FLAG_PRECIOUS			= 0x20;
+	public static final byte		FLAG_PUT_AND_FORGET		= 0x40;				// local only
+	public static final byte		FLAG_OBFUSCATE_LOOKUP	= (byte)0x80;		// local only
 
 	public static final int 	MAX_VALUE_SIZE		= 512;
 
+	public static final byte	REP_FACT_NONE			= 0;
+	public static final byte	REP_FACT_DEFAULT		= (byte)0xff;
+	
 		// diversification types, don't change as serialised!!!!
 	
 	public static final byte	DT_NONE			= 1;
@@ -113,6 +117,17 @@ DHT
 		boolean					high_priority,
 		DHTOperationListener	listener );
 
+	public void
+	put(
+		byte[]					key,
+		String					description,
+		byte[]					value,
+		byte					flags,
+		byte					life_hours,
+		byte					replication_control,	// 4 bits 1->14 republish hours; 0=vuze default | 4 bits 0->15 maintain replicas; [ff=no replication control-use default]
+		boolean					high_priority,
+		DHTOperationListener	listener );
+	
 		/**
 		 * Returns value if originated from here for key
 		 * @param key
diff --git a/com/aelitis/azureus/core/dht/DHTOperationAdapter.java b/com/aelitis/azureus/core/dht/DHTOperationAdapter.java
index e89572a..8275509 100644
--- a/com/aelitis/azureus/core/dht/DHTOperationAdapter.java
+++ b/com/aelitis/azureus/core/dht/DHTOperationAdapter.java
@@ -47,10 +47,11 @@ DHTOperationAdapter
 		String		desc )
 	{
 	}
-	
+		
 	public void
 	found(
-		DHTTransportContact	contact )
+		DHTTransportContact	contact,
+		boolean				is_closest )
 	{
 	}
 	
diff --git a/com/aelitis/azureus/core/dht/DHTOperationListener.java b/com/aelitis/azureus/core/dht/DHTOperationListener.java
index 91df7b7..8fc7477 100644
--- a/com/aelitis/azureus/core/dht/DHTOperationListener.java
+++ b/com/aelitis/azureus/core/dht/DHTOperationListener.java
@@ -45,7 +45,8 @@ DHTOperationListener
 	
 	public void
 	found(
-		DHTTransportContact	contact );
+		DHTTransportContact		contact,
+		boolean					is_closest );
 	
 	public void
 	read(
diff --git a/com/aelitis/azureus/core/dht/DHTStorageAdapter.java b/com/aelitis/azureus/core/dht/DHTStorageAdapter.java
index 2492bd1..d312e8a 100644
--- a/com/aelitis/azureus/core/dht/DHTStorageAdapter.java
+++ b/com/aelitis/azureus/core/dht/DHTStorageAdapter.java
@@ -99,6 +99,7 @@ DHTStorageAdapter
 	
 	public byte[][]
 	createNewDiversification(
+		String				description,
 		DHTTransportContact	cause,
 		byte[]				key,
 		boolean				put_operation,
diff --git a/com/aelitis/azureus/core/dht/control/DHTControl.java b/com/aelitis/azureus/core/dht/control/DHTControl.java
index 09acc8c..f4e07ec 100644
--- a/com/aelitis/azureus/core/dht/control/DHTControl.java
+++ b/com/aelitis/azureus/core/dht/control/DHTControl.java
@@ -53,6 +53,9 @@ DHTControl
 	seed(
 		boolean		full_wait );
 		
+	public boolean
+	isSeeded();
+	
 	public void
 	put(
 		byte[]					key,
@@ -60,6 +63,7 @@ DHTControl
 		byte[]					value,
 		byte					flags,
 		byte					life_hours,
+		byte					replication_control,
 		boolean					high_priority,
 		DHTOperationListener	listener );
 	
@@ -125,20 +129,16 @@ DHTControl
 	
 		// support methods for DB
 	
-	public List
+	public List<DHTTransportContact>
 	getClosestKContactsList(
 		byte[]		id,
 		boolean		live_only );
 	
-	public List
+	public List<DHTTransportContact>
 	getClosestContactsList(
 		byte[]		id,
 		int			num_to_return,
 		boolean		live_only );
-
-	public List
-	sortContactsByDistance(
-		List		contacts );
 	
 	public void
 	putEncodedKey(
@@ -150,10 +150,18 @@ DHTControl
 	
 	public void
 	putDirectEncodedKeys(
-		byte[][]				keys,
-		String					description,
-		DHTTransportValue[][]	value_sets,
-		List					contacts );
+		byte[][]					keys,
+		String						description,
+		DHTTransportValue[][]		value_sets,
+		List<DHTTransportContact>	contacts );
+	
+	public void
+	putDirectEncodedKeys(
+		byte[][]					keys,
+		String						description,
+		DHTTransportValue[][]		value_sets,
+		DHTTransportContact			contact,
+		DHTOperationListener		listener );
 	
 	public int
 	computeAndCompareDistances(
@@ -161,6 +169,16 @@ DHTControl
 		byte[]		n2,
 		byte[]		pivot );
 	
+	public byte[]
+	computeDistance(
+		byte[]		n1,
+		byte[]		n2 );
+	
+	public int
+	compareDistances(
+		byte[]		n1,
+		byte[]		n2 );
+	
 	public boolean
 	verifyContact(
 		DHTTransportContact c,
@@ -169,15 +187,28 @@ DHTControl
 	public boolean
 	lookup(
 		byte[]					id,
+		String					description,
 		long					timeout,
 		DHTOperationListener	listener );
 	
+	public boolean
+	lookupEncoded(
+		byte[]					id,
+		String					description,
+		long					timeout,
+		boolean					high_priority,
+		DHTOperationListener	listener );
+	
+	public byte[]
+	getObfuscatedKey(
+		byte[]		plain_key );
+	
 	/**
-	 * Returns a list of DHTContact objects
+	 * Returns a list of DHTTransportContact objects
 	 * @return
 	 */
 	
-	public List
+	public List<DHTTransportContact>
 	getContacts();
 	
 		// debug method only
diff --git a/com/aelitis/azureus/core/dht/control/DHTControlAdapter.java b/com/aelitis/azureus/core/dht/control/DHTControlAdapter.java
index 626ac48..f135058 100644
--- a/com/aelitis/azureus/core/dht/control/DHTControlAdapter.java
+++ b/com/aelitis/azureus/core/dht/control/DHTControlAdapter.java
@@ -38,6 +38,7 @@ DHTControlAdapter
 
 	public byte[][]
 	diversify(
+		String				description,
 		DHTTransportContact	cause,
 		boolean				put_operation,
 		boolean				existing,
diff --git a/com/aelitis/azureus/core/dht/control/impl/DHTControlImpl.java b/com/aelitis/azureus/core/dht/control/impl/DHTControlImpl.java
index 4a221de..71c9c55 100644
--- a/com/aelitis/azureus/core/dht/control/impl/DHTControlImpl.java
+++ b/com/aelitis/azureus/core/dht/control/impl/DHTControlImpl.java
@@ -33,6 +33,9 @@ import javax.crypto.Cipher;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.engines.RC4Engine;
+import org.bouncycastle.crypto.params.KeyParameter;
 import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.dht.*;
@@ -60,6 +63,8 @@ public class
 DHTControlImpl 
 	implements DHTControl, DHTTransportRequestHandler
 {
+	private static final boolean DISABLE_REPLICATE_ON_JOIN	= true;
+	
 	private static final int EXTERNAL_LOOKUP_CONCURRENCY	= 16;
 	private static final int EXTERNAL_PUT_CONCURRENCY		= 8;
 	
@@ -98,6 +103,8 @@ DHTControlImpl
 	
 	private Map			imported_state	= new HashMap();
 	
+	private volatile boolean	seeded;
+	
 	private long		last_lookup;
 	
 
@@ -147,10 +154,14 @@ DHTControlImpl
 
 	private Cipher 			spoof_cipher;
 	private SecretKey		spoof_key;
+	private DHTTransportContact	spoof_last_verify_contact;
+	private int					spoof_last_verify_result;
 	
 	private long			last_node_add_check;
 	private byte[]			node_add_check_uninteresting_limit;
 	
+	private long			rbs_time;
+	private byte[]			rbs_id	= {};
 	
 	public
 	DHTControlImpl(
@@ -185,6 +196,7 @@ DHTControlImpl
 						adapter.getStorageAdapter(),
 						_original_republish_interval,
 						_cache_republish_interval,
+						transport.getProtocolVersion(),
 						logger );
 					
 		internal_lookup_pool 	= new ThreadPool("DHTControl:internallookups", lookup_concurrency );
@@ -641,6 +653,8 @@ DHTControlImpl
 							sem.release();
 						}
 						
+						seeded = true;
+						
 						try{
 							
 							router.seed();
@@ -684,6 +698,12 @@ DHTControlImpl
 		}
 	}
 	
+	public boolean
+	isSeeded()
+	{
+		return( seeded );
+	}
+	
 	protected void
 	poke()
 	{
@@ -733,6 +753,7 @@ DHTControlImpl
 		byte[]					_value,
 		byte					_flags,
 		byte					_life_hours,
+		byte					_replication_control,
 		boolean					_high_priority,
 		DHTOperationListener	_listener )
 	{
@@ -751,13 +772,14 @@ DHTControlImpl
 			DHTLog.log( "put for " + DHTLog.getString( encoded_key ));
 		}
 		
-		DHTDBValue	value = database.store( new HashWrapper( encoded_key ), _value, _flags, _life_hours );
+		DHTDBValue	value = database.store( new HashWrapper( encoded_key ), _value, _flags, _life_hours, _replication_control );
 		
 		put( 	external_put_pool,
 				_high_priority,
 				encoded_key, 
 				_description,
 				value, 
+				_flags,
 				0, 
 				true,
 				new HashSet(),
@@ -780,6 +802,7 @@ DHTControlImpl
 				encoded_key, 
 				description, 
 				value, 
+				(byte)0,
 				timeout, 
 				original_mappings,
 				new HashSet(),
@@ -795,6 +818,7 @@ DHTControlImpl
 		byte[]						initial_encoded_key,
 		String						description,
 		DHTTransportValue			value,
+		byte						flags,
 		long						timeout,
 		boolean						original_mappings,
 		Set							things_written,
@@ -806,6 +830,7 @@ DHTControlImpl
 				initial_encoded_key, 
 				description, 
 				new DHTTransportValue[]{ value }, 
+				flags,
 				timeout,
 				original_mappings,
 				things_written,
@@ -820,6 +845,7 @@ DHTControlImpl
 		final byte[]						initial_encoded_key,
 		final String						description,
 		final DHTTransportValue[]			values,
+		final byte							flags,
 		final long							timeout,
 		final boolean						original_mappings,
 		final Set							things_written,
@@ -831,6 +857,7 @@ DHTControlImpl
 		
 		byte[][]	encoded_keys	= 
 			adapter.diversify( 
+					description,
 					null, 
 					true, 
 					true, 
@@ -879,7 +906,7 @@ DHTControlImpl
 					high_priority,
 					encoded_key,
 					this_description,
-					(byte)0,
+					flags,
 					false, 
 					timeout,
 					search_concurrency,
@@ -904,6 +931,7 @@ DHTControlImpl
 									new byte[][]{ encoded_key }, 
 									"Store of [" + this_description + "]",
 									new DHTTransportValue[][]{ values }, 
+									flags,
 									_closest, 
 									timeout, 
 									listener, 
@@ -932,6 +960,7 @@ DHTControlImpl
 				encoded_keys, 
 				description,
 				value_sets, 
+				(byte)0,
 				contacts, 
 				0, 
 				new DHTOperationListenerDemuxer( new DHTOperationAdapter()),
@@ -941,6 +970,166 @@ DHTControlImpl
 				false );
 	}
 		
+	public void
+	putDirectEncodedKeys(
+		byte[][]				encoded_keys,
+		String					description,
+		DHTTransportValue[][]	value_sets,
+		DHTTransportContact		contact,
+		DHTOperationListener	listener )
+	{
+			// we don't consider diversification for direct puts (these are for republishing
+			// of cached mappings and we maintain these as normal - its up to the original
+			// publisher to diversify as required)
+		
+		List<DHTTransportContact> contacts = new ArrayList<DHTTransportContact>(1);
+		
+		contacts.add( contact );
+		
+		put( 	internal_put_pool,
+				false,
+				encoded_keys, 
+				description,
+				value_sets, 
+				(byte)0,
+				contacts, 
+				0, 
+				new DHTOperationListenerDemuxer( listener ),
+				false,
+				new HashSet(),
+				1,
+				false );
+	}
+	
+	public byte[]
+	getObfuscatedKey(
+		byte[]		plain_key )
+	{
+		int	length = plain_key.length;
+		
+		byte[]	obs_key = new byte[ length ];
+		
+		System.arraycopy( plain_key, 0, obs_key, 0, 5 );
+		
+			// ensure plain key and obfuscated one differ at subsequent bytes to prevent potential 
+			// clashes with code that uses 'n' byte prefix (e.g. DB survey code)
+		
+		for (int i=6;i<length;i++){
+		
+			if ( plain_key[i] == 0 ){
+			
+				obs_key[i] = 1;
+			}
+		}
+		
+			// finally copy over last two bytes for code that uses challenge-response on this
+			// (survey code)
+		
+		obs_key[length-2] = plain_key[length-2];
+		obs_key[length-1] = plain_key[length-1];
+		
+		return( obs_key );
+	}
+	
+	protected byte[]
+	getObfuscatedValue(
+		byte[]		plain_key )
+	{
+        RC4Engine	engine = new RC4Engine();
+        
+		CipherParameters	params = new KeyParameter( new SHA1Simple().calculateHash( plain_key ));
+		
+		engine.init( true, params ); 
+
+		byte[]	temp = new byte[1024];
+		
+		engine.processBytes( temp, 0, 1024, temp, 0 );
+		
+		final byte[] obs_value = new byte[ plain_key.length ];
+		
+		engine.processBytes( plain_key, 0, plain_key.length, obs_value, 0 );
+		
+		return( obs_value );
+	}
+	
+	protected DHTTransportValue
+	getObfuscatedValue(
+		final DHTTransportValue		basis,
+		byte[]						plain_key )
+	{		
+		final byte[] obs_value = getObfuscatedValue( plain_key );
+				
+		return( 
+			new DHTTransportValue()
+			{
+				public boolean
+				isLocal()
+				{
+					return( basis.isLocal());
+				}
+				
+				public long
+				getCreationTime()
+				{
+					return( basis.getCreationTime());
+				}
+				
+				public byte[]
+				getValue()
+				{
+					return( obs_value );
+				}
+				
+				public int
+				getVersion()
+				{	
+					return( basis.getVersion());
+				}
+				
+				public DHTTransportContact
+				getOriginator()
+				{
+					return( basis.getOriginator());
+				}
+				
+				public int
+				getFlags()
+				{
+					return( basis.getFlags());
+				}
+				
+				public int
+				getLifeTimeHours()
+				{
+					return( basis.getLifeTimeHours());
+				}
+				
+				public byte
+				getReplicationControl()
+				{
+					return( basis.getReplicationControl());
+				}
+				
+				public byte
+				getReplicationFactor()
+				{
+					return( basis.getReplicationFactor());
+				}
+				
+				public byte 
+				getReplicationFrequencyHours() 
+				{
+					return( basis.getReplicationFrequencyHours());
+				}
+				
+				public String
+				getString()
+				{
+					return( "obs: " + basis.getString());
+				}
+			});
+	}
+	
 	protected void
 	put(
 		final ThreadPool						thread_pool,
@@ -948,6 +1137,7 @@ DHTControlImpl
 		byte[][]								initial_encoded_keys,
 		final String							description,
 		final DHTTransportValue[][]				initial_value_sets,
+		final byte								flags,
 		final List								contacts,
 		final long								timeout,
 		final DHTOperationListenerDemuxer		listener,
@@ -1011,6 +1201,32 @@ DHTControlImpl
 			}
 		}
 		
+		final byte[][] 				obs_keys;
+		final DHTTransportValue[][]	obs_vals;
+
+		if ( ( flags & DHT.FLAG_OBFUSCATE_LOOKUP ) != 0 ){
+		
+			if ( encoded_keys.length != 1 ){
+				
+				Debug.out( "inconsistent - expected one key" );
+			}
+			
+			if ( value_sets[0].length != 1 ){
+				
+				Debug.out( "inconsistent - expected one value" );
+			}
+			
+			obs_keys	= new byte[1][];
+			obs_vals	= new DHTTransportValue[1][1];
+
+			obs_keys[0] 	= getObfuscatedKey( encoded_keys[0] );
+			obs_vals[0][0]	= getObfuscatedValue( value_sets[0][0], encoded_keys[0] );
+		}else{
+			
+			obs_keys	= null;
+			obs_vals	= null;
+		}
+		
 			// only diversify on one hit as we're storing at closest 'n' so we only need to
 			// do it once for each key
 		
@@ -1020,7 +1236,7 @@ DHTControlImpl
 		
 		for (int i=0;i<contacts.size();i++){
 		
-			DHTTransportContact	contact = (DHTTransportContact)contacts.get(i);
+			final DHTTransportContact	contact = (DHTTransportContact)contacts.get(i);
 			
 			if ( router.isID( contact.getID())){
 					
@@ -1076,6 +1292,8 @@ DHTControlImpl
 									DHTTransportContact _contact,
 									byte[]				_diversifications )
 								{
+									boolean	complete_is_async = false;
+									
 									try{
 										if ( DHTLog.isOn()){
 											DHTLog.log( "Store OK " + DHTLog.getString( _contact ));
@@ -1085,16 +1303,20 @@ DHTControlImpl
 									
 											// can be null for old protocol versions
 										
+										boolean div_done = false;
+										
 										if ( consider_diversification && _diversifications != null ){
 																			
 											for (int j=0;j<_diversifications.length;j++){
 												
 												if ( _diversifications[j] != DHT.DT_NONE && !diversified[j] ){
 													
+													div_done = true;
+													
 													diversified[j]	= true;
 													
 													byte[][]	diversified_keys = 
-														adapter.diversify( _contact, true, false, encoded_keys[j], _diversifications[j], false, getMaxDivDepth());
+														adapter.diversify( description, _contact, true, false, encoded_keys[j], _diversifications[j], false, getMaxDivDepth());
 												
 													
 													logDiversification( _contact, encoded_keys, diversified_keys );
@@ -1106,6 +1328,7 @@ DHTControlImpl
 																diversified_keys[k], 
 																"Diversification of [" + description + "]",
 																value_sets[j], 
+																flags,
 																timeout,
 																false,
 																things_written,
@@ -1115,9 +1338,51 @@ DHTControlImpl
 												}
 											}
 										}
+										
+										if ( !div_done ){
+											
+											if ( obs_keys != null ){
+																								
+												contact.sendStore( 
+														new DHTTransportReplyHandlerAdapter()
+														{
+															public void
+															storeReply(
+																DHTTransportContact _contact,
+																byte[]				_diversifications )
+															{
+																if ( DHTLog.isOn()){
+																	DHTLog.log( "Obs store OK " + DHTLog.getString( _contact ));
+																}
+
+																listener.complete( false );
+															}
+															
+															public void
+															failed(
+																DHTTransportContact 	_contact,
+																Throwable 				_error )
+															{
+																if ( DHTLog.isOn()){
+																	DHTLog.log( "Obs store failed " + DHTLog.getString( _contact ) + " -> failed: " + _error.getMessage());
+																}
+
+																listener.complete( true );
+															}
+														},
+														obs_keys,
+														obs_vals,
+														immediate );
+												
+												complete_is_async = true;
+											}
+										}
 									}finally{
 										
-										listener.complete( false );
+										if ( !complete_is_async ){
+										
+											listener.complete( false );
+										}
 									}	
 								}
 								
@@ -1302,9 +1567,10 @@ DHTControlImpl
 					
 					public void
 					found(
-						DHTTransportContact	contact )
+						DHTTransportContact	contact,
+						boolean				is_closest )
 					{
-						get_listener.found(contact);
+						get_listener.found(contact,is_closest);
 					}
 					
 					public void
@@ -1352,11 +1618,21 @@ DHTControlImpl
 	public boolean
    	lookup(		
    		byte[]							unencoded_key,
+   		String							description,
    		long							timeout,
    		final DHTOperationListener		lookup_listener )
 	{
-		final byte[]	encoded_key = encodeKey( unencoded_key );
-
+		return( lookupEncoded( encodeKey( unencoded_key ), description, timeout, false, lookup_listener ));
+	}
+	
+	public boolean
+   	lookupEncoded(		
+   		byte[]							encoded_key,
+   		String							description,
+   		long							timeout,
+   		boolean							high_priority,
+   		final DHTOperationListener		lookup_listener )
+	{
 		if ( DHTLog.isOn()){
 			DHTLog.log( "lookup for " + DHTLog.getString( encoded_key ));
 		}
@@ -1379,7 +1655,8 @@ DHTControlImpl
 				
 				public void
 				found(
-					DHTTransportContact	contact )
+					DHTTransportContact	contact,
+					boolean				is_closest )
 				{
 				}
 				
@@ -1414,9 +1691,10 @@ DHTControlImpl
 				}
 			};
 			
-		lookup( 	external_lookup_pool, false,
+		lookup( 	external_lookup_pool, 
+					high_priority,
 					encoded_key, 
-					"lookup",
+					description,
 					(byte)0,
 					false, 
 					timeout,
@@ -1441,7 +1719,7 @@ DHTControlImpl
 						{
 							for (int i=0;i<closest.size();i++){
 								
-								lookup_listener.found((DHTTransportContact)closest.get(i));
+								lookup_listener.found((DHTTransportContact)closest.get(i),true);
 							}
 						}
 					});
@@ -1466,7 +1744,7 @@ DHTControlImpl
 		
 			// get the initial starting point for the get - may have previously been diversified
 		
-		byte[][]	encoded_keys	= adapter.diversify( null, false, true, initial_encoded_key, DHT.DT_NONE, exhaustive, getMaxDivDepth());
+		byte[][]	encoded_keys	= adapter.diversify( description, null, false, true, initial_encoded_key, DHT.DT_NONE, exhaustive, getMaxDivDepth());
 
 		if  ( encoded_keys.length == 0 ){
 		
@@ -1529,7 +1807,7 @@ DHTControlImpl
 								
 								if ( max_values == 0 || rem > 0 ){
 									
-									byte[][]	diversified_keys = adapter.diversify( cause, false, false, encoded_key, diversification_type, exhaustive, getMaxDivDepth());
+									byte[][]	diversified_keys = adapter.diversify( description, cause, false, false, encoded_key, diversification_type, exhaustive, getMaxDivDepth());
 									
 									if ( diversified_keys.length > 0 ){
 										
@@ -1648,6 +1926,7 @@ DHTControlImpl
 					encoded_key, 
 					description, 
 					res,
+					(byte)res.getFlags(),
 					0, 
 					true, 
 					new HashSet(),
@@ -1693,6 +1972,7 @@ DHTControlImpl
 					new byte[][]{ encoded_key }, 
 					"Store of [" + description + "]",
 					new DHTTransportValue[][]{{ res }}, 
+					(byte)res.getFlags(),
 					contacts_l, 
 					0, 
 					new DHTOperationListenerDemuxer( listener ), 
@@ -1716,7 +1996,7 @@ DHTControlImpl
 	lookup(
 		final ThreadPool 			thread_pool, 
 		boolean 					high_priority, 
-		final byte[] 				lookup_id, 
+		final byte[] 				_lookup_id, 
 		final String 				description, 
 		final byte 					flags, 
 		final boolean 				value_search, 
@@ -1726,6 +2006,20 @@ DHTControlImpl
 		final int 					search_accuracy, 
 		final lookupResultHandler 	handler )
 	{
+		final byte[] 	lookup_id;
+		final byte[]	obs_value;
+		
+		if (( flags & DHT.FLAG_OBFUSCATE_LOOKUP ) != 0 ){
+			
+			lookup_id 	= getObfuscatedKey( _lookup_id );
+			obs_value	= getObfuscatedValue( _lookup_id );
+			
+		}else{
+			
+			lookup_id 	= _lookup_id;
+			obs_value	= null;
+		}
+				
 		DhtTask	task =
 			new DhtTask(thread_pool)
 			{
@@ -1805,7 +2099,7 @@ DHTControlImpl
 					while (it.hasNext())
 					{
 						DHTTransportContact contact = (DHTTransportContact) it.next();
-						handler.found(contact);
+						handler.found(contact,false);
 						level_map.put(contact, new Integer(0));
 					}
 					
@@ -2046,6 +2340,9 @@ DHTControlImpl
 											closest = vp_closest;
 									}
 								}
+								
+								final DHTTransportContact f_closest = closest;
+								
 								contacts_to_query.remove(closest);
 								contacts_queried.put(new HashWrapper(closest.getID()), closest);
 								// never search ourselves!
@@ -2105,7 +2402,7 @@ DHTControlImpl
 														}
 														
 														contacts_to_query.add(contact);
-														handler.found(contact);
+														handler.found(contact,false);
 														level_map.put(contact, new Integer(search_level + 1));
 														if (idle_searches > 0)
 														{
@@ -2135,11 +2432,26 @@ DHTControlImpl
 										}
 									}
 
-									public void findValueReply(DHTTransportContact contact, DHTTransportValue[] values, byte diversification_type, boolean more_to_come) {
+									public void 
+									findValueReply(
+										DHTTransportContact 	contact, 
+										DHTTransportValue[] 	values, 
+										byte 					diversification_type, 	// hack - this is set to 99 when recursing here during obsfuscated lookup
+										boolean 				more_to_come )
+									{
 										if ( DHTLog.isOn()){
 											DHTLog.log("findValueReply: " + DHTLog.getString(values) + ",mtc=" + more_to_come + ", dt=" + diversification_type);
 										}
 										
+										boolean	obs_recurse = false;
+										
+										if ( diversification_type == 99 ){
+											
+											obs_recurse = true;
+											
+											diversification_type = DHT.DT_NONE;
+										}
+										
 										try
 										{
 											if (!key_blocked && diversification_type != DHT.DT_NONE){
@@ -2172,11 +2484,53 @@ DHTControlImpl
 													System.arraycopy(originator_id, 0, value_id, 0, originator_id.length);
 													System.arraycopy(value_bytes, 0, value_id, originator_id.length, value_bytes.length);
 													HashWrapper x = new HashWrapper(value_id);
-													if (!values_found_set.contains(x))
-													{
-														new_values++;
-														values_found_set.add(x);
-														handler.read(contact, values[i]);
+													
+													if ( !values_found_set.contains(x)){
+														
+														if ( obs_value != null && ! obs_recurse ){
+														
+																// we have read the marker value, now issue a direct read with the 
+																// real key
+															
+															if ( Arrays.equals( obs_value, value_bytes )){
+															
+																more_to_come = true;
+															
+																final DHTTransportReplyHandlerAdapter f_outer = this;
+																
+																f_closest.sendFindValue( 
+																	new DHTTransportReplyHandlerAdapter()
+																	{
+																		public void
+																		findValueReply(
+																			DHTTransportContact 	contact, 
+																			DHTTransportValue[] 	values, 
+																			byte 					diversification_type, 
+																			boolean 				more_to_come )
+																		{
+																			if ( diversification_type == DHT.DT_NONE ){
+																			
+																				f_outer.findValueReply( contact, values, (byte)99, false );
+																			}
+																		}
+																		
+																		public void 
+																		failed(
+																			DHTTransportContact 	contact,
+																			Throwable 				error )
+																		{
+																			f_outer.failed( contact, error );
+																		}
+																	},
+																	_lookup_id, 1, flags );
+																
+																break;
+															}
+														}else{
+															new_values++;
+															values_found_set.add(x);
+															handler.read(contact, values[i]);
+														}
 													}
 												}
 											}
@@ -2332,7 +2686,9 @@ DHTControlImpl
 		byte[][]				keys,
 		DHTTransportValue[][]	value_sets )
 	{
-		router.contactAlive( originating_contact.getID(), new DHTControlContactImpl(originating_contact));
+		byte[] originator_id = originating_contact.getID();
+		
+		router.contactAlive( originator_id, new DHTControlContactImpl(originating_contact));
 		
 		if ( DHTLog.isOn()){
 		
@@ -2350,25 +2706,134 @@ DHTControlImpl
 			return( new DHTTransportStoreReplyImpl(  diverse_res ));
 		}
 		
+		DHTStorageBlock	blocked_details	= null;
+
 		// System.out.println( "storeRequest: received " + originating_contact.getRandomID() + " from " + originating_contact.getAddress());
 		
-		DHTStorageBlock	blocked_details	= null;
+		//System.out.println( "store request: keys=" + keys.length );
 		
-		for (int i=0;i<keys.length;i++){
+		if ( keys.length > 0 ){
 			
-			HashWrapper			key		= new HashWrapper( keys[i] );
+			boolean	cache_forward = false;
 			
-			DHTTransportValue[]	values 	= value_sets[i];
-		
-			if ( DHTLog.isOn()){
-				DHTLog.log( "    key=" + DHTLog.getString(key) + ", value=" + DHTLog.getString(values));
+			for ( DHTTransportValue[] values: value_sets ){
+				
+				for ( DHTTransportValue value: values ){
+				
+					if ( !Arrays.equals( originator_id, value.getOriginator().getID())){
+						
+						cache_forward	= true;
+					
+						break;
+					}
+				}
+				
+				if ( cache_forward ){
+						
+					break;
+				}
 			}
 			
-			diverse_res[i] = database.store( originating_contact, key, values );
+				// don't start accepting cache forwards until we have a good idea of our 
+				// acceptable key space
+							
+			if ( cache_forward && !isSeeded()){
+				
+				//System.out.println( "not seeded" );
+				
+				if ( DHTLog.isOn()){
+					DHTLog.log( "Not storing keys as not yet seeded" );
+				}
+				
+			}else if ( !verifyContact( originating_contact, !cache_forward )){
+					
+				//System.out.println( "verification fail" );
+				
+				logger.log( "Verification of contact '" + originating_contact.getName() + "' failed for store operation" );
+				
+			}else{
+				
+					// get the closest contacts to me
+					
+				byte[]	my_id	= local_contact.getID();
+				
+				int	c_factor = router.getK();
+				
+				if ( adapter.getStorageAdapter().getNetwork() != DHT.NW_CVS ){
+					
+					c_factor += ( c_factor/2 );
+				}
+
+				boolean store_it = true;
+				
+				if ( cache_forward ){
+					
+					long	now = SystemTime.getMonotonousTime();
+					
+					if ( now - rbs_time < 10*1000 && Arrays.equals( originator_id, rbs_id )){
+						
+						// System.out.println( "contact too far away - repeat" );
+						
+						store_it = false;
+						
+					}else{
+							// make sure the originator is in our group
+						
+						List<DHTTransportContact>closest_contacts = getClosestContactsList( my_id, c_factor, true );
+						
+						DHTTransportContact	furthest = closest_contacts.get( closest_contacts.size()-1);
+							
+						if ( computeAndCompareDistances( furthest.getID(), originator_id, my_id ) < 0 ){
 			
-			if ( blocked_details == null ){
+							rbs_id 		= originator_id;
+							rbs_time	= now;
+							
+							// System.out.println( "contact too far away" );
+		
+							if ( DHTLog.isOn()){
+								DHTLog.log( "Not storing keys as cache forward and sender too far away" );
+							}
+							
+							store_it	= false;
+						}
+					}
+				}
+								
+				if ( store_it ){
 					
-				blocked_details = database.getKeyBlockDetails( keys[i] );
+					for (int i=0;i<keys.length;i++){
+						
+						byte[]			key = keys[i];
+						
+						HashWrapper		hw_key		= new HashWrapper( key );
+						
+						DHTTransportValue[]	values 	= value_sets[i];
+					
+						if ( DHTLog.isOn()){
+							DHTLog.log( "    key=" + DHTLog.getString(key) + ", value=" + DHTLog.getString(values));
+						}
+						
+							// make sure the key isn't too far away from us
+						
+						if ( 	!( 	database.hasKey( hw_key ) ||
+									isIDInClosestContacts( my_id, key, c_factor, true ))){
+							
+							// System.out.println( "key too far away" );
+		
+							if ( DHTLog.isOn()){
+								DHTLog.log( "Not storing keys as cache forward and sender too far away" );
+							}
+						}else{					
+							
+							diverse_res[i] = database.store( originating_contact, hw_key, values );
+							
+							if ( blocked_details == null ){
+									
+								blocked_details = database.getKeyBlockDetails( key );
+							}
+						}
+					}
+				}
 			}
 		}
 		
@@ -2385,6 +2850,26 @@ DHTControlImpl
 		}
 	}
 	
+	public DHTTransportQueryStoreReply
+	queryStoreRequest(
+		DHTTransportContact 		originating_contact, 
+		int							header_len,
+		List<Object[]>				keys )
+	{
+		router.contactAlive( originating_contact.getID(), new DHTControlContactImpl(originating_contact));
+		
+		if ( DHTLog.isOn()){
+		
+			DHTLog.log( "queryStoreRequest from " + DHTLog.getString( originating_contact )+ ", header_len=" + header_len + ", keys=" + keys.size());
+		}
+
+		int	rand = generateSpoofID( originating_contact );
+		
+		originating_contact.setRandomID( rand );
+
+		return( database.queryStore( originating_contact, header_len, keys ));
+	}
+	
 	public DHTTransportContact[]
 	findNodeRequest(
 		DHTTransportContact originating_contact, 
@@ -2498,6 +2983,16 @@ DHTControlImpl
 	nodeAddedToRouter(
 		DHTRouterContact	new_contact )
 	{	
+		if ( DISABLE_REPLICATE_ON_JOIN ){
+			
+			if ( !new_contact.hasBeenAlive()){
+				
+				requestPing( new_contact );
+			}
+				
+			return;
+		}
+		
 			// ignore ourselves
 		
 		if ( router.isID( new_contact.getID())){
@@ -2606,6 +3101,8 @@ DHTControlImpl
 			return;
 		}
 			
+		// System.out.println( "Node added to router: id=" + ByteFormatter.encodeString( contact_id ));
+		
 			// ok, we're close enough to worry about transferring values				
 		
 		Iterator	it = database.getKeys();
@@ -2903,19 +3400,21 @@ DHTControlImpl
 		}
 	}
 	
-	protected Set
+	protected Set<DHTTransportContact>
 	getClosestContactsSet(
 		byte[]		id,
 		int			num_to_return,
 		boolean		live_only )
 	{
-		List	l = router.findClosestContacts( id, num_to_return, live_only );
+		List<DHTRouterContact>	l = router.findClosestContacts( id, num_to_return, live_only );
 		
-		Set	sorted_set	= new sortedTransportContactSet( id, true ).getSet(); 
+		Set<DHTTransportContact>	sorted_set	= new sortedTransportContactSet( id, true ).getSet(); 
 
-		// profilers says l.size() is taking CPU (!) so put it into a variable
-		// this is safe since the list returned is created for us only
+			// profilers says l.size() is taking CPU (!) so put it into a variable
+			// this is safe since the list returned is created for us only
+		
 		long size = l.size();
+		
 		for (int i=0;i<size;i++){
 			
 			sorted_set.add(((DHTControlContactImpl)((DHTRouterContact)l.get(i)).getAttachment()).getTransportContact());
@@ -2924,7 +3423,7 @@ DHTControlImpl
 		return( sorted_set );
 	}
 	
-	public List
+	public List<DHTTransportContact>
 	getClosestKContactsList(
 		byte[]		id,
 		boolean		live_only )
@@ -2932,17 +3431,17 @@ DHTControlImpl
 		return( getClosestContactsList( id, K, live_only ));
 	}
 	
-	public List
+	public List<DHTTransportContact>
 	getClosestContactsList(
 		byte[]		id,
 		int			num_to_return,
 		boolean		live_only )
 	{
-		Set	sorted_set	= getClosestContactsSet( id, num_to_return, live_only );
+		Set<DHTTransportContact>	sorted_set	= getClosestContactsSet( id, num_to_return, live_only );
 					
-		List	res = new ArrayList(num_to_return);
+		List<DHTTransportContact>	res = new ArrayList<DHTTransportContact>(num_to_return);
 		
-		Iterator	it = sorted_set.iterator();
+		Iterator<DHTTransportContact>	it = sorted_set.iterator();
 		
 		while( it.hasNext() && res.size() < num_to_return ){
 			
@@ -2952,6 +3451,38 @@ DHTControlImpl
 		return( res );
 	}
 	
+	protected boolean
+	isIDInClosestContacts(
+		byte[]		test_id,
+		byte[]		target_id,
+		int			num_to_consider,
+		boolean		live_only )
+	{
+		List<DHTRouterContact>	l = router.findClosestContacts( target_id, num_to_consider, live_only );
+		
+		boolean	found		= false;
+		int		num_closer 	= 0;
+		
+		for ( DHTRouterContact c: l ){
+			
+			byte[]	c_id = c.getID();
+			
+			if ( Arrays.equals( test_id, c_id )){
+				
+				found = true;
+				
+			}else{
+			
+				if ( computeAndCompareDistances( c_id, test_id, target_id ) < 0 ){
+					
+					num_closer++;
+				}
+			}
+		}
+		
+		return( found && num_closer < num_to_consider );
+	}
+	
 	protected byte[]
 	encodeKey(
 		byte[]		key )
@@ -3332,21 +3863,21 @@ DHTControlImpl
 	IDToBigInteger(
 		byte[]		data )
 	{
-		String	str_key = "";
+		StringBuilder	str_key = new StringBuilder( data.length*2 );
 		
 		for (int i=0;i<data.length;i++){
 			
 			String	hex = Integer.toHexString( data[i]&0xff );
 			
-			while( hex.length() < 2 ){
+			if ( hex.length() < 2 ){
 				
-				hex = "0" + hex;
+				str_key.append( "0" );
 			}
 				
-			str_key += hex;
+			str_key.append( hex );
 		}
 				
-		BigInteger	res		= new BigInteger( str_key, 16 );	
+		BigInteger	res		= new BigInteger( str_key.toString(), 16 );	
 		
 		return( res );
 	}
@@ -3363,6 +3894,14 @@ DHTControlImpl
 		try{
 			spoof_mon.enter();
 			
+				// during cache forwarding we get a lot of consecutive requests from the
+				// same contact so we can save CPU by caching the latest result and optimising for this
+			
+			if ( contact == spoof_last_verify_contact ){
+								
+				return( spoof_last_verify_result );
+			}
+			
 			spoof_cipher.init(Cipher.ENCRYPT_MODE, spoof_key ); 
 		
 			byte[]	address = contact.getAddress().getAddress().getAddress();
@@ -3376,6 +3915,9 @@ DHTControlImpl
 			
 			// System.out.println( "anti-spoof: generating " + res + " for " + contact.getAddress());
 
+			spoof_last_verify_contact 	= contact;
+			spoof_last_verify_result	= res;
+			
 			return( res );
 
 		}catch( Throwable e ){
@@ -3505,21 +4047,10 @@ DHTControlImpl
 		*/
 	}
 	
-	public List
-	sortContactsByDistance(
-		List		contacts )
-	{
-		Set	sorted_contacts = new sortedTransportContactSet( router.getID(), true ).getSet(); 
-
-		sorted_contacts.addAll( contacts );
-		
-		return( new ArrayList( sorted_contacts ));
-	}
-	
 	protected static class
 	sortedTransportContactSet
 	{
-		private TreeSet	tree_set;
+		private TreeSet<DHTTransportContact>	tree_set;
 		
 		private byte[]	pivot;
 		private boolean	ascending;
@@ -3532,20 +4063,17 @@ DHTControlImpl
 			pivot		= _pivot;
 			ascending	= _ascending;
 			
-			tree_set = new TreeSet(
-				new Comparator()
+			tree_set = new TreeSet<DHTTransportContact>(
+				new Comparator<DHTTransportContact>()
 				{
 					public int
 					compare(
-						Object	o1,
-						Object	o2 )
+						DHTTransportContact	t1,
+						DHTTransportContact	t2 )
 					{
 							// this comparator ensures that the closest to the key
 							// is first in the iterator traversal
-					
-						DHTTransportContact	t1 = (DHTTransportContact)o1;
-						DHTTransportContact t2 = (DHTTransportContact)o2;
-											
+							 									
 						int	distance = computeAndCompareDistances2( t1.getID(), t2.getID(), pivot );
 						
 						if ( ascending ){
@@ -3560,7 +4088,7 @@ DHTControlImpl
 				});
 		}
 		
-		public Set
+		public Set<DHTTransportContact>
 		getSet()
 		{
 			return( tree_set );
@@ -3624,9 +4152,10 @@ DHTControlImpl
 		
 		public void
 		found(
-			DHTTransportContact	contact )
+			DHTTransportContact	contact,
+			boolean				is_closest )
 		{
-			delegate.found( contact );
+			delegate.found( contact, is_closest );
 		}
 		
 		public void
@@ -3855,6 +4384,24 @@ DHTControlImpl
 			return( delegate.getLifeTimeHours());
 		}
 		
+		public byte
+		getReplicationControl()
+		{
+			return( delegate.getReplicationControl());
+		}
+		
+		public byte 
+		getReplicationFactor() 
+		{
+			return( delegate.getReplicationFactor());
+		}
+		
+		public byte 
+		getReplicationFrequencyHours() 
+		{
+			return( delegate.getReplicationFrequencyHours());
+		}
+		
 		public String
 		getString()
 		{
@@ -3963,6 +4510,14 @@ DHTControlImpl
 			return( delegate.isAlive( timeout ));
 		}
 
+		public void
+		isAlive(
+			DHTTransportReplyHandler	handler,
+			long						timeout )
+		{
+			delegate.isAlive( handler, timeout );
+		}
+		
 		public boolean
 		isValid()
 		{
@@ -4001,6 +4556,15 @@ DHTControlImpl
 			delegate.sendStore(handler, keys, value_sets, immediate);
 		}
 		
+		public void 
+		sendQueryStore(
+			DHTTransportReplyHandler 	handler,
+			int							header_length,
+			List<Object[]>			 	key_details ) 
+		{
+			delegate.sendQueryStore( handler, header_length, key_details );
+		}
+		
 		public void
 		sendFindNode(
 			DHTTransportReplyHandler	handler,
diff --git a/com/aelitis/azureus/core/dht/db/DHTDB.java b/com/aelitis/azureus/core/dht/db/DHTDB.java
index 3e1c31f..9f620f5 100644
--- a/com/aelitis/azureus/core/dht/db/DHTDB.java
+++ b/com/aelitis/azureus/core/dht/db/DHTDB.java
@@ -23,12 +23,14 @@
 package com.aelitis.azureus.core.dht.db;
 
 import java.util.Iterator;
+import java.util.List;
 
 import org.gudy.azureus2.core3.util.HashWrapper;
 
 import com.aelitis.azureus.core.dht.DHTStorageBlock;
 import com.aelitis.azureus.core.dht.control.DHTControl;
 import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
+import com.aelitis.azureus.core.dht.transport.DHTTransportQueryStoreReply;
 import com.aelitis.azureus.core.dht.transport.DHTTransportValue;
 
 /**
@@ -56,7 +58,8 @@ DHTDB
 		HashWrapper		key,
 		byte[]			value,
 		byte			flags,
-		byte			life_hours );
+		byte			life_hours,
+		byte			replication_control );
 	
 		/**
 		 * Remote store
@@ -73,6 +76,12 @@ DHTDB
 		HashWrapper				key,
 		DHTTransportValue[]		values );
 	
+	public DHTTransportQueryStoreReply
+	queryStore(
+		DHTTransportContact 		originating_contact, 
+		int							header_len,
+		List<Object[]>				keys );
+	
 		/**
 		 * Internal lookup for locally originated values
 		 * @param key
@@ -83,6 +92,10 @@ DHTDB
 	get(
 		HashWrapper		key );
 	
+	public boolean
+	hasKey(
+		HashWrapper		key );
+	
 	public DHTDBLookupResult
 	get(
 		DHTTransportContact		reader,
@@ -129,7 +142,7 @@ DHTDB
 		 * @return
 		 */
 	
-	public Iterator
+	public Iterator<HashWrapper>
 	getKeys();
 	
 	public DHTDBStats
diff --git a/com/aelitis/azureus/core/dht/db/DHTDBFactory.java b/com/aelitis/azureus/core/dht/db/DHTDBFactory.java
index acb8ced..b35c67f 100644
--- a/com/aelitis/azureus/core/dht/db/DHTDBFactory.java
+++ b/com/aelitis/azureus/core/dht/db/DHTDBFactory.java
@@ -39,12 +39,14 @@ DHTDBFactory
 		DHTStorageAdapter	adapter,
 		int					original_republish_interval,
 		int					cache_republish_interval,
+		byte				protocol_version,
 		DHTLogger			logger )
 	{
 		return( new DHTDBImpl( 
 					adapter,
 					original_republish_interval, 
 					cache_republish_interval, 
+					protocol_version,
 					logger ));
 	}
 }
diff --git a/com/aelitis/azureus/core/dht/db/impl/DHTDBImpl.java b/com/aelitis/azureus/core/dht/db/impl/DHTDBImpl.java
index 2a23a81..c3908cf 100644
--- a/com/aelitis/azureus/core/dht/db/impl/DHTDBImpl.java
+++ b/com/aelitis/azureus/core/dht/db/impl/DHTDBImpl.java
@@ -31,8 +31,11 @@ import org.gudy.azureus2.core3.ipfilter.IpFilterManagerFactory;
 import org.gudy.azureus2.core3.util.AEMonitor;
 import org.gudy.azureus2.core3.util.AESemaphore;
 import org.gudy.azureus2.core3.util.AEThread2;
+import org.gudy.azureus2.core3.util.ByteArrayHashMap;
+import org.gudy.azureus2.core3.util.ByteFormatter;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.HashWrapper;
+import org.gudy.azureus2.core3.util.RandomUtils;
 import org.gudy.azureus2.core3.util.SimpleTimer;
 import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.core3.util.TimerEvent;
@@ -41,6 +44,7 @@ import org.gudy.azureus2.core3.util.TimerEventPerformer;
 
 import com.aelitis.azureus.core.dht.DHT;
 import com.aelitis.azureus.core.dht.DHTLogger;
+import com.aelitis.azureus.core.dht.DHTOperationAdapter;
 import com.aelitis.azureus.core.dht.DHTStorageAdapter;
 import com.aelitis.azureus.core.dht.DHTStorageBlock;
 import com.aelitis.azureus.core.dht.DHTStorageKey;
@@ -50,9 +54,11 @@ import com.aelitis.azureus.core.dht.impl.DHTLog;
 import com.aelitis.azureus.core.dht.router.DHTRouter;
 import com.aelitis.azureus.core.dht.control.DHTControl;
 import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
+import com.aelitis.azureus.core.dht.transport.DHTTransportQueryStoreReply;
 import com.aelitis.azureus.core.dht.transport.DHTTransportReplyHandlerAdapter;
 import com.aelitis.azureus.core.dht.transport.DHTTransportValue;
 import com.aelitis.azureus.core.dht.transport.udp.DHTTransportUDP;
+import com.aelitis.azureus.core.util.FeatureAvailability;
 import com.aelitis.azureus.core.util.bloom.BloomFilter;
 import com.aelitis.azureus.core.util.bloom.BloomFilterFactory;
 
@@ -65,7 +71,7 @@ public class
 DHTDBImpl
 	implements DHTDB, DHTDBStats
 {	
-	private static final long MAX_VALUE_LIFETIME	= 3*24*60*60*1000L;
+	private static final int MAX_VALUE_LIFETIME	= 3*24*60*60*1000;
 	
 	
 	private int			original_republish_interval;
@@ -75,7 +81,8 @@ DHTDBImpl
 	
 	public static int			ORIGINAL_REPUBLISH_INTERVAL_GRACE	= 60*60*1000;
 	
-	private static final int	PRECIOUS_CHECK_INTERVAL				= 2*60*60*1000;
+	private static final boolean	ENABLE_PRECIOUS_STUFF			= false;
+	private static final int		PRECIOUS_CHECK_INTERVAL			= 2*60*60*1000;
 	
 	private int			cache_republish_interval;
 	
@@ -92,7 +99,11 @@ DHTDBImpl
 	private int next_value_version_left;
 	
 	
-	private Map			stored_values = new HashMap();
+	protected static final int		QUERY_STORE_REQUEST_ENTRY_SIZE	= 6;
+	protected static final int		QUERY_STORE_REPLY_ENTRY_SIZE	= 2;
+	
+	private Map<HashWrapper,DHTDBMapping>				stored_values 				= new HashMap<HashWrapper,DHTDBMapping>();
+	private Map<DHTDBMapping.ShortHash,DHTDBMapping>	stored_values_prefix_map	= new HashMap<DHTDBMapping.ShortHash,DHTDBMapping>();
 	
 	private DHTControl				control;
 	private DHTStorageAdapter		adapter;
@@ -114,31 +125,70 @@ DHTDBImpl
 
 	private AEMonitor	this_mon	= new AEMonitor( "DHTDB" );
 
+	private static final boolean	DEBUG_SURVEY		= false;
+	private static final boolean	SURVEY_ONLY_RF_KEYS	= true;
+	
+	
+	private static final int	SURVEY_PERIOD					= DEBUG_SURVEY?1*60*1000:15*60*1000;
+	private static final int	SURVEY_STATE_INACT_TIMEOUT		= DEBUG_SURVEY?5*60*1000:60*60*1000;
+	private static final int	SURVEY_STATE_MAX_LIFE_TIMEOUT	= 3*60*60*1000 + 30*60*1000;
+	private static final int	SURVEY_STATE_MAX_LIFE_RAND		= 1*60*60*1000;
+	
+	private static final int	MAX_SURVEY_SIZE			= 100;
+	private static final int	MAX_SURVEY_STATE_SIZE	= 150;
+	
+	private final boolean	survey_enabled;
+	
+	private volatile boolean survey_in_progress;
+		
+	private Map<HashWrapper,Long>	survey_mapping_times = new HashMap<HashWrapper, Long>();
+	
+	private Map<HashWrapper,SurveyContactState>	survey_state = 
+		new LinkedHashMap<HashWrapper,SurveyContactState>(MAX_SURVEY_STATE_SIZE,0.75f,true)
+		{
+			protected boolean 
+			removeEldestEntry(
+		   		Map.Entry<HashWrapper,SurveyContactState> eldest) 
+			{
+				return size() > MAX_SURVEY_STATE_SIZE;
+			}
+		};
+		
 	public
 	DHTDBImpl(
 		DHTStorageAdapter	_adapter,
 		int					_original_republish_interval,
 		int					_cache_republish_interval,
+		byte				_protocol_version,
 		DHTLogger			_logger )
 	{
 		adapter							= _adapter==null?null:new adapterFacade( _adapter );
 		original_republish_interval		= _original_republish_interval;
 		cache_republish_interval		= _cache_republish_interval;
 		logger							= _logger;
-				
-		SimpleTimer.addPeriodicEvent(
-			"DHTDB:precious",
-			PRECIOUS_CHECK_INTERVAL/4,
-			true, // absolute, we don't want effective time changes (computer suspend/resume) to shift these
-			new TimerEventPerformer()
-			{
-				public void
-				perform(
-					TimerEvent	event )
+			
+		survey_enabled = 
+			_protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL3 &&
+			(	adapter == null || 
+				adapter.getNetwork() == DHT.NW_CVS || 
+				FeatureAvailability.isDHTRepV2Enabled());
+		
+		if ( ENABLE_PRECIOUS_STUFF ){
+			
+			SimpleTimer.addPeriodicEvent(
+				"DHTDB:precious",
+				PRECIOUS_CHECK_INTERVAL/4,
+				true, // absolute, we don't want effective time changes (computer suspend/resume) to shift these
+				new TimerEventPerformer()
 				{
-					checkPreciousStuff();
-				}
-			});
+					public void
+					perform(
+						TimerEvent	event )
+					{
+						checkPreciousStuff();
+					}
+				});
+		}
 		
 		SimpleTimer.addPeriodicEvent(
 			"DHTDB:op",
@@ -228,7 +278,23 @@ DHTDBImpl
 						}
 					}
 				});
-						
+				
+		if ( survey_enabled ){
+			
+			SimpleTimer.addPeriodicEvent(
+					"DHTDB:survey",
+					SURVEY_PERIOD,
+					true, 
+					new TimerEventPerformer()
+					{
+						public void
+						perform(
+							TimerEvent	event )
+						{
+							survey();
+						}
+					});
+		}
 	}
 	
 	
@@ -250,11 +316,13 @@ DHTDBImpl
 		try{
 			this_mon.enter();
 			
-			Iterator	it = stored_values.values().iterator();
+			survey_state.clear();
+			
+			Iterator<DHTDBMapping>	it = stored_values.values().iterator();
 			
 			while( it.hasNext()){
 				
-				DHTDBMapping	mapping = (DHTDBMapping)it.next();
+				DHTDBMapping	mapping = it.next();
 				
 				mapping.updateLocalContact( local_contact );
 			}
@@ -269,12 +337,18 @@ DHTDBImpl
 		HashWrapper		key,
 		byte[]			value,
 		byte			flags,
-		byte			life_hours )
+		byte			life_hours,
+		byte			replication_control )
 	{
 			// local store
 		
 		if ( (flags & DHT.FLAG_PUT_AND_FORGET ) == 0 ){
 			
+			if (( flags & DHT.FLAG_OBFUSCATE_LOOKUP ) != 0 ){
+				
+				Debug.out( "Obfuscated puts without 'put-and-forget' are not supported as original-republishing of them is not implemented" );
+			}
+			
 			if ( life_hours > 0 ){
 				
 				if ( life_hours*60*60*1000 < original_republish_interval ){
@@ -300,6 +374,8 @@ DHTDBImpl
 					mapping = new DHTDBMapping( this, key, true );
 					
 					stored_values.put( key, mapping );
+					
+					addToPrefixMap( mapping );
 				}
 				
 				DHTDBValueImpl res =	
@@ -311,7 +387,8 @@ DHTDBImpl
 							local_contact,
 							true,
 							flags,
-							life_hours );
+							life_hours,
+							replication_control );
 		
 				mapping.add( res );
 				
@@ -332,7 +409,8 @@ DHTDBImpl
 						local_contact,
 						true,
 						flags,
-						life_hours );
+						life_hours,
+						replication_control );
 			
 			return( res );
 		}
@@ -366,96 +444,6 @@ DHTDBImpl
 			return( DHT.DT_SIZE );
 		}
 		
-			// remote store for cache values
-		
-			// Make sure that we only accept values for storing that are reasonable.
-			// Assumption is that the caller has made a reasonable effort to ascertain
-			// the correct place to store a value. Part of this will in general have 
-			// needed them to query us for example. Therefore, limit values to those
-			// that are at least as close to us
-			// used to just use K here but this is a little too strict as we end up rejecting
-			// a fair few valid stores - widened to 2*K
-		
-			// dropped a bit, especially on CVS DHT due to smallness
-		
-		int	c_factor = router.getK();
-		
-		if ( adapter.getNetwork() != DHT.NW_CVS ){
-			
-			c_factor += ( c_factor/2 );
-		}
-		
-		List closest_contacts = control.getClosestContactsList( key.getHash(), c_factor, true );
-		
-		boolean	store_it	= false;
-		
-		
-		// store_ops++;
-		
-		for (int i=0;i<closest_contacts.size();i++){
-			
-			if ( router.isID(((DHTTransportContact)closest_contacts.get(i)).getID())){
-				
-				store_it	= true;
-				
-				break;
-			}		
-		}
-		
-		if ( !store_it ){
-			
-			DHTLog.log( "Not storing " + DHTLog.getString2(key.getHash()) + " as key too far away" );
-
-			// store_ops_bad1++;
-			// logStoreOps();
-			
-			return( DHT.DT_NONE );
-		}
-		
-			// next, for cache forwards (rather then values coming directly from 
-			// originators) we ensure that the contact sending the values to us is
-			// close enough. If any values are coming indirect then we can safely assume
-			// that they all are
-		
-		boolean	cache_forward = false;
-		
-		for (int i=0;i<values.length;i++){
-			
-			if (!Arrays.equals( sender.getID(), values[i].getOriginator().getID())){
-				
-				cache_forward	= true;
-				
-				break;
-			}
-		}
-		
-		
-		if ( cache_forward ){
-			
-				// get the closest contacts to me
-				
-			byte[]	my_id	= local_contact.getID();
-			
-			closest_contacts = control.getClosestContactsList( my_id, c_factor, true );
-			
-			DHTTransportContact	furthest = (DHTTransportContact)closest_contacts.get( closest_contacts.size()-1);
-						
-			if ( control.computeAndCompareDistances( furthest.getID(), sender.getID(), my_id ) < 0 ){
-
-				store_it	= false;
-			}
-		}
-		
-		if ( !store_it ){
-			
-			DHTLog.log( "Not storing " + DHTLog.getString2(key.getHash()) + " as cache forward and sender too far away" );
-			
-			// store_ops_bad2++;			
-			// logStoreOps();
-			
-			return( DHT.DT_NONE );
-		}
-		
 		// logStoreOps();
 		
 		try{
@@ -470,47 +458,20 @@ DHTDBImpl
 				mapping = new DHTDBMapping( this, key, false );
 				
 				stored_values.put( key, mapping );
+				
+				addToPrefixMap( mapping );
 			}
-			
-			boolean contact_checked = false;
-			boolean	contact_ok		= false;
-			
+						
 				// we carry on an update as its ok to replace existing entries
 				// even if diversified
 			
 			for (int i=0;i<values.length;i++){
 				
-					// last check, verify that the contact is who they say they are, only for non-forwards
-					// as cache forwards are only accepted if they are "close enough" and we can't 
-					// rely on their identify due to the way that cache republish works (it doesn't
-					// guarantee a "lookup_node" prior to "store".
-
 				DHTTransportValue	value = values[i];
-				
-				boolean	ok_to_store = false;
-				
-				boolean	direct =Arrays.equals( sender.getID(), value.getOriginator().getID());
-								
-				if ( !contact_checked ){
-						
-					contact_ok =  control.verifyContact( sender, direct );
-						
-					if ( !contact_ok ){
-						
-						logger.log( "DB: verification of contact '" + sender.getName() + "' failed for store operation" );
-					}
 					
-					contact_checked	= true;
-				}
+				DHTDBValueImpl mapping_value	= new DHTDBValueImpl( sender, value, false );
 			
-				ok_to_store	= contact_ok;
-
-				if ( ok_to_store ){
-					
-					DHTDBValueImpl mapping_value	= new DHTDBValueImpl( sender, value, false );
-			
-					mapping.add( mapping_value );
-				}
+				mapping.add( mapping_value );
 			}
 			
 			return( mapping.getDiversificationType());
@@ -594,6 +555,21 @@ DHTDBImpl
 		}
 	}
 	
+	public boolean
+	hasKey(
+		HashWrapper		key )
+	{
+		try{
+			this_mon.enter();
+			
+			return( stored_values.containsKey( key ));
+			
+		}finally{
+			
+			this_mon.exit();
+		}
+	}
+	
 	public DHTDBValue
 	remove(
 		DHTTransportContact 	originator,
@@ -646,13 +622,13 @@ DHTDBImpl
 			
 			byte[]	key = adapter.getKeyForKeyBlock( request );
 			
-			List closest_contacts = control.getClosestKContactsList( key, true );
+			List<DHTTransportContact> closest_contacts = control.getClosestKContactsList( key, true );
 			
 			boolean	process_it	= false;
 			
 			for (int i=0;i<closest_contacts.size();i++){
 				
-				if ( router.isID(((DHTTransportContact)closest_contacts.get(i)).getID())){
+				if ( router.isID(closest_contacts.get(i).getID())){
 					
 					process_it	= true;
 					
@@ -746,11 +722,11 @@ DHTDBImpl
 			
 			int[]	res = new int[6];
 			
-			Iterator	it = stored_values.values().iterator();
+			Iterator<DHTDBMapping>	it = stored_values.values().iterator();
 			
 			while( it.hasNext()){
 				
-				DHTDBMapping	mapping = (DHTDBMapping)it.next();
+				DHTDBMapping	mapping = it.next();
 				
 				res[DHTDBStats.VD_VALUE_COUNT] += mapping.getValueCount();
 				res[DHTDBStats.VD_LOCAL_SIZE] += mapping.getLocalSize();
@@ -766,6 +742,19 @@ DHTDBImpl
 				}else if ( dt == DHT.DT_SIZE ){
 					
 					res[DHTDBStats.VD_DIV_SIZE]++;
+					
+					/*
+					Iterator<DHTDBValueImpl> it2 = mapping.getIndirectValues();
+					
+					System.out.println( "values=" + mapping.getValueCount());
+					
+					while( it2.hasNext()){
+						
+						DHTDBValueImpl val = it2.next();
+						
+						System.out.println( new String( val.getValue()) + " - " + val.getOriginator().getAddress());
+					}
+					*/
 				}
 			}
 			
@@ -788,13 +777,13 @@ DHTDBImpl
 		return( adapter.getDirectKeyBlocks().length );
 	}
 	
-	public Iterator
+	public Iterator<HashWrapper>
 	getKeys()
 	{
 		try{
 			this_mon.enter();
 			
-			return( new ArrayList( stored_values.keySet()).iterator());
+			return( new ArrayList<HashWrapper>( stored_values.keySet()).iterator());
 			
 		}finally{
 			
@@ -807,28 +796,28 @@ DHTDBImpl
 	{
 		int	values_published	= 0;
 
-		Map	republish = new HashMap();
+		Map<HashWrapper,List<DHTDBValueImpl>>	republish = new HashMap<HashWrapper,List<DHTDBValueImpl>>();
 		
 		try{
 			this_mon.enter();
 			
-			Iterator	it = stored_values.entrySet().iterator();
+			Iterator<Map.Entry<HashWrapper,DHTDBMapping>>	it = stored_values.entrySet().iterator();
 			
 			while( it.hasNext()){
 				
-				Map.Entry	entry = (Map.Entry)it.next();
+				Map.Entry<HashWrapper,DHTDBMapping>	entry = it.next();
 				
 				HashWrapper		key		= (HashWrapper)entry.getKey();
 				
 				DHTDBMapping	mapping	= (DHTDBMapping)entry.getValue();
 				
-				Iterator	it2 = mapping.getValues();
+				Iterator<DHTDBValueImpl>	it2 = mapping.getValues();
 				
-				List	values = new ArrayList();
+				List<DHTDBValueImpl>	values = new ArrayList<DHTDBValueImpl>();
 				
 				while( it2.hasNext()){
 					
-					DHTDBValueImpl	value = (DHTDBValueImpl)it2.next();
+					DHTDBValueImpl	value = it2.next();
 				
 					if ( value != null && value.isLocal()){
 						
@@ -851,15 +840,15 @@ DHTDBImpl
 			this_mon.exit();
 		}
 		
-		Iterator	it = republish.entrySet().iterator();
+		Iterator<Map.Entry<HashWrapper,List<DHTDBValueImpl>>>	it = republish.entrySet().iterator();
 		
 		while( it.hasNext()){
 			
-			Map.Entry	entry = (Map.Entry)it.next();
+			Map.Entry<HashWrapper,List<DHTDBValueImpl>>	entry = it.next();
 			
 			HashWrapper			key		= (HashWrapper)entry.getKey();
 			
-			List		values	= (List)entry.getValue();
+			List<DHTDBValueImpl>		values	= entry.getValue();
 			
 				// no point in worry about multi-value puts here as it is extremely unlikely that
 				// > 1 value will locally stored, or > 1 value will go to the same contact
@@ -868,7 +857,7 @@ DHTDBImpl
 				
 				values_published++;
 				
-				control.putEncodedKey( key.getHash(), "Republish", (DHTDBValueImpl)values.get(i), 0, true );
+				control.putEncodedKey( key.getHash(), "Republish", values.get(i), 0, true );
 			}
 		}
 		
@@ -883,7 +872,9 @@ DHTDBImpl
 		
 		router.refreshIdleLeaves( cache_republish_interval );
 		
-		final Map	republish = new HashMap();
+		final Map<HashWrapper,List<DHTDBValueImpl>>	republish = new HashMap<HashWrapper,List<DHTDBValueImpl>>();
+		
+		List<DHTDBMapping>	republish_via_survey = new ArrayList<DHTDBMapping>();
 		
 		long	now = System.currentTimeMillis();
 		
@@ -892,15 +883,15 @@ DHTDBImpl
 			
 			checkCacheExpiration( true );
 
-			Iterator	it = stored_values.entrySet().iterator();
+			Iterator<Map.Entry<HashWrapper,DHTDBMapping>>	it = stored_values.entrySet().iterator();
 			
 			while( it.hasNext()){
 				
-				Map.Entry	entry = (Map.Entry)it.next();
+				Map.Entry<HashWrapper,DHTDBMapping>	entry = it.next();
 				
-				HashWrapper			key		= (HashWrapper)entry.getKey();
+				HashWrapper			key		= entry.getKey();
 				
-				DHTDBMapping		mapping	= (DHTDBMapping)entry.getValue();
+				DHTDBMapping		mapping	= entry.getValue();
 				
 					// assume that if we've diversified then the other k-1 locations are under similar
 					// stress and will have done likewise - no point in republishing cache values to them
@@ -912,16 +903,23 @@ DHTDBImpl
 					continue;
 				}
 				
-				Iterator	it2 = mapping.getValues();
+				Iterator<DHTDBValueImpl>	it2 = mapping.getValues();
 				
-				List	values = new ArrayList();
+				boolean	all_rf_values = it2.hasNext();
+				
+				List<DHTDBValueImpl>	values = new ArrayList<DHTDBValueImpl>();
 				
 				while( it2.hasNext()){
 					
-					DHTDBValueImpl	value = (DHTDBValueImpl)it2.next();
+					DHTDBValueImpl	value = it2.next();
 				
 					if ( !value.isLocal()){
 						
+						if ( value.getReplicationFactor() == DHT.REP_FACT_DEFAULT ){
+							
+							all_rf_values = false;
+						}
+						
 							// if this value was stored < period ago then we assume that it was
 							// also stored to the other k-1 locations at the same time and therefore
 							// we don't need to re-store it
@@ -943,10 +941,19 @@ DHTDBImpl
 					}
 				}
 
-				if ( values.size() > 0 ){
+				if ( all_rf_values ){
 					
-					republish.put( key, values );
+						// if surveying is disabled then we swallow values here to prevent them
+						// from being replicated using the existing technique and muddying the waters
 					
+					values.clear();	// handled by the survey process
+					
+					republish_via_survey.add( mapping );
+				}
+					
+				if ( values.size() > 0 ){
+						
+					republish.put( key, values );
 				}
 			}
 		}finally{
@@ -954,11 +961,71 @@ DHTDBImpl
 			this_mon.exit();
 		}
 		
+		if ( republish_via_survey.size() > 0 ){
+		
+				// we still check for being too far away here
+			
+			List<HashWrapper>	stop_caching = new ArrayList<HashWrapper>();
+
+			for ( DHTDBMapping mapping: republish_via_survey ){
+				
+				HashWrapper			key		= mapping.getKey();
+				
+				byte[]	lookup_id	= key.getHash();
+
+				List<DHTTransportContact>	contacts = control.getClosestKContactsList( lookup_id, false );
+				
+					// if we are no longer one of the K closest contacts then we shouldn't
+					// cache the value
+			
+				boolean	keep_caching	= false;
+			
+				for (int j=0;j<contacts.size();j++){
+			
+					if ( router.isID(((DHTTransportContact)contacts.get(j)).getID())){
+					
+						keep_caching	= true;
+					
+						break;
+					}
+				}
+			
+				if ( !keep_caching ){
+					
+					DHTLog.log( "Dropping cache entry for " + DHTLog.getString( lookup_id ) + " as now too far away" );
+					
+					stop_caching.add( key );
+				}
+			}
+			
+			if ( stop_caching.size() > 0 ){
+				
+				try{
+					this_mon.enter();
+					
+					for (int i=0;i<stop_caching.size();i++){
+						
+						DHTDBMapping	mapping = (DHTDBMapping)stored_values.remove( stop_caching.get(i));
+						
+						if ( mapping != null ){
+							
+							removeFromPrefixMap( mapping );
+							
+							mapping.destroy();
+						}
+					}
+				}finally{
+					
+					this_mon.exit();
+				}
+			}
+		}
+		
 		final int[]	values_published	= {0};
 		final int[]	keys_published		= {0};
 		final int[]	republish_ops		= {0};
 		
-		final HashSet	anti_spoof_done	= new HashSet();
+		final HashSet<DHTTransportContact>	anti_spoof_done	= new HashSet<DHTTransportContact>();
 		
 		if ( republish.size() > 0 ){
 			
@@ -972,19 +1039,19 @@ DHTDBImpl
 				// (that's required to keep the DHT alive in general) to ensure that all
 				// k-buckets are reasonably up-to-date
 					
-			Iterator	it = republish.entrySet().iterator();
+			Iterator<Map.Entry<HashWrapper,List<DHTDBValueImpl>>>	it1 = republish.entrySet().iterator();
 			
-			List	stop_caching = new ArrayList();
+			List<HashWrapper>	stop_caching = new ArrayList<HashWrapper>();
 			
 				// build a map of contact -> list of keys to republish
 			
-			Map	contact_map	= new HashMap();
+			Map<HashWrapper,Object[]>	contact_map	= new HashMap<HashWrapper,Object[]>();
 			
-			while( it.hasNext()){
+			while( it1.hasNext()){
 				
-				Map.Entry	entry = (Map.Entry)it.next();
+				Map.Entry<HashWrapper,List<DHTDBValueImpl>>	entry = it1.next();
 				
-				HashWrapper			key		= (HashWrapper)entry.getKey();
+				HashWrapper			key		= entry.getKey();
 				
 				byte[]	lookup_id	= key.getHash();
 				
@@ -993,7 +1060,7 @@ DHTDBImpl
 					// is a bad idea as failures may rack up against the live ones due
 					// to network problems and kill them, leaving the dead ones!
 				
-				List	contacts = control.getClosestKContactsList( lookup_id, false );
+				List<DHTTransportContact>	contacts = control.getClosestKContactsList( lookup_id, false );
 							
 					// if we are no longer one of the K closest contacts then we shouldn't
 					// cache the value
@@ -1033,20 +1100,20 @@ DHTDBImpl
 					
 					if ( data == null ){
 						
-						data	= new Object[]{ contact, new ArrayList()};
+						data	= new Object[]{ contact, new ArrayList<HashWrapper>()};
 						
 						contact_map.put( new HashWrapper(contact.getID()), data );
 					}
 					
-					((List)data[1]).add( key );
+					((List<HashWrapper>)data[1]).add( key );
 				}
 			}
 		
-			it = contact_map.values().iterator();
+			Iterator<Object[]> it2 = contact_map.values().iterator();
 			
-			while( it.hasNext()){
+			while( it2.hasNext()){
 				
-				final Object[]	data = (Object[])it.next();
+				final Object[]	data = it2.next();
 				
 				final DHTTransportContact	contact = (DHTTransportContact)data[0];
 				
@@ -1068,7 +1135,7 @@ DHTDBImpl
 								try{
 									// System.out.println( "cacheForward: pre-store findNode OK" );
 								
-									List				keys	= (List)data[1];
+									List<HashWrapper>				keys	= (List<HashWrapper>)data[1];
 										
 									byte[][]				store_keys 		= new byte[keys.size()][];
 									DHTTransportValue[][]	store_values 	= new DHTTransportValue[store_keys.length][];
@@ -1077,11 +1144,11 @@ DHTDBImpl
 									
 									for (int i=0;i<store_keys.length;i++){
 										
-										HashWrapper	wrapper = (HashWrapper)keys.get(i);
+										HashWrapper	wrapper = keys.get(i);
 										
 										store_keys[i] = wrapper.getHash();
 										
-										List		values	= (List)republish.get( wrapper );
+										List<DHTDBValueImpl>		values	= republish.get( wrapper );
 										
 										store_values[i] = new DHTTransportValue[values.size()];
 							
@@ -1089,7 +1156,7 @@ DHTDBImpl
 										
 										for (int j=0;j<values.size();j++){
 										
-											DHTDBValueImpl	value	= (DHTDBValueImpl)values.get(j);
+											DHTDBValueImpl	value	= values.get(j);
 												
 												// we reduce the cache distance by 1 here as it is incremented by the
 												// recipients
@@ -1098,7 +1165,7 @@ DHTDBImpl
 										}
 									}
 										
-									List	contacts = new ArrayList();
+									List<DHTTransportContact>	contacts = new ArrayList<DHTTransportContact>();
 									
 									contacts.add( contact );
 									
@@ -1147,6 +1214,8 @@ DHTDBImpl
 					
 					if ( mapping != null ){
 						
+						removeFromPrefixMap( mapping );
+						
 						mapping.destroy();
 					}
 				}
@@ -1288,25 +1357,27 @@ DHTDBImpl
 			
 			last_cache_expiry_check	= now;
 			
-			Iterator	it = stored_values.values().iterator();
+			Iterator<DHTDBMapping>	it = stored_values.values().iterator();
 			
 			while( it.hasNext()){
 				
-				DHTDBMapping	mapping = (DHTDBMapping)it.next();
+				DHTDBMapping	mapping = it.next();
 	
 				if ( mapping.getValueCount() == 0 ){
 										
 					it.remove();
 					
+					removeFromPrefixMap( mapping );
+					
 					mapping.destroy();
 
 				}else{
 					
-					Iterator	it2 = mapping.getValues();
+					Iterator<DHTDBValueImpl>	it2 = mapping.getValues();
 					
 					while( it2.hasNext()){
 						
-						DHTDBValueImpl	value = (DHTDBValueImpl)it2.next();				
+						DHTDBValueImpl	value = it2.next();				
 						
 						if ( !value.isLocal()){
 							
@@ -1316,7 +1387,7 @@ DHTDBImpl
 							
 							int life_hours = value.getLifeTimeHours();
 							
-							long	max_age;
+							int	max_age;
 							
 							if ( life_hours < 1 ){
 								
@@ -1332,7 +1403,20 @@ DHTDBImpl
 								}
 							}
 							
-							if ( now > value.getCreationTime() + max_age + ORIGINAL_REPUBLISH_INTERVAL_GRACE ){
+							int	grace;
+							
+							if (( value.getFlags() & DHT.FLAG_PUT_AND_FORGET ) != 0 ){
+								
+								grace = 0;
+								
+							}else{
+								
+									// scale the grace period for short lifetimes
+								
+								grace = Math.min( ORIGINAL_REPUBLISH_INTERVAL_GRACE, max_age/4 );
+							}
+							
+							if ( now > value.getCreationTime() + max_age + grace ){
 								
 								DHTLog.log( "removing cache entry (" + value.getString() + ")" );
 								
@@ -1349,33 +1433,77 @@ DHTDBImpl
 	}
 	
 	protected void
+	addToPrefixMap(
+		DHTDBMapping		mapping )
+	{
+		DHTDBMapping.ShortHash key = mapping.getShortKey();
+		
+		DHTDBMapping existing = stored_values_prefix_map.get( key );
+		
+			// possible to have clashes, be consistent in which one we use to avoid
+			// confusing other nodes
+		
+		if ( existing != null ){
+			
+			byte[]	existing_full 	= existing.getKey().getBytes();
+			byte[]	new_full		= mapping.getKey().getBytes();
+			
+			if ( control.computeAndCompareDistances( existing_full, new_full, local_contact.getID()) < 0 ){
+				
+				return;
+			}
+		}
+		
+		stored_values_prefix_map.put( key, mapping );
+	
+		if ( stored_values_prefix_map.size() > stored_values.size()){
+			
+			Debug.out( "inconsistent" );
+		}
+	}
+	
+	protected void
+	removeFromPrefixMap(
+		DHTDBMapping		mapping )
+	{
+		DHTDBMapping.ShortHash key = mapping.getShortKey();
+
+		DHTDBMapping existing = stored_values_prefix_map.get( key );
+	
+		if ( existing == mapping ){
+			
+			stored_values_prefix_map.remove( key );
+		}
+	}
+	
+	protected void
 	checkPreciousStuff()
 	{
 		long	 now = SystemTime.getCurrentTime();
 		
-		Map	republish = new HashMap();
+		Map<HashWrapper,List<DHTDBValueImpl>>	republish = new HashMap<HashWrapper,List<DHTDBValueImpl>>();
 
 		try{
 
 			this_mon.enter();
 						
-			Iterator	it = stored_values.entrySet().iterator();
+			Iterator<Map.Entry<HashWrapper,DHTDBMapping>>	it = stored_values.entrySet().iterator();
 			
 			while( it.hasNext()){
 				
-				Map.Entry	entry = (Map.Entry)it.next();
+				Map.Entry<HashWrapper,DHTDBMapping>	entry = it.next();
 				
-				HashWrapper		key		= (HashWrapper)entry.getKey();
+				HashWrapper		key		= entry.getKey();
 				
-				DHTDBMapping	mapping	= (DHTDBMapping)entry.getValue();
+				DHTDBMapping	mapping	= entry.getValue();
 
-				Iterator	it2 = mapping.getValues();
+				Iterator<DHTDBValueImpl>	it2 = mapping.getValues();
 				
-				List	values = new ArrayList();
+				List<DHTDBValueImpl>	values = new ArrayList<DHTDBValueImpl>();
 
 				while( it2.hasNext()){
 					
-					DHTDBValueImpl	value = (DHTDBValueImpl)it2.next();				
+					DHTDBValueImpl	value = it2.next();				
 
 					if ( value.isLocal()){
 						
@@ -1402,23 +1530,22 @@ DHTDBImpl
 			this_mon.exit();
 		}
 		
-		
-		Iterator	it = republish.entrySet().iterator();
+		Iterator<Map.Entry<HashWrapper,List<DHTDBValueImpl>>>	it = republish.entrySet().iterator();
 		
 		while( it.hasNext()){
 			
-			Map.Entry	entry = (Map.Entry)it.next();
+			Map.Entry<HashWrapper,List<DHTDBValueImpl>>	entry = it.next();
 			
-			HashWrapper			key		= (HashWrapper)entry.getKey();
+			HashWrapper			key		= entry.getKey();
 			
-			List		values	= (List)entry.getValue();
+			List<DHTDBValueImpl>		values	= entry.getValue();
 			
 				// no point in worry about multi-value puts here as it is extremely unlikely that
 				// > 1 value will locally stored, or > 1 value will go to the same contact
 			
 			for (int i=0;i<values.size();i++){
 								
-				control.putEncodedKey( key.getHash(), "Precious republish", (DHTDBValueImpl)values.get(i), 0, true );
+				control.putEncodedKey( key.getHash(), "Precious republish", values.get(i), 0, true );
 			}
 		}
 	}
@@ -1448,11 +1575,1350 @@ DHTDBImpl
 		return( this );
 	}
 	
+	protected void
+	survey()
+	{
+		if ( survey_in_progress ){
+			
+			return;
+		}
+		
+		if ( DEBUG_SURVEY ){
+			System.out.println( "surveying" );
+		}
+		
+		checkCacheExpiration( false );
+		
+		final byte[]	my_id = router.getID();
+		
+		if ( DEBUG_SURVEY ){
+			System.out.println( "    my_id=" + ByteFormatter.encodeString( my_id ));
+		}
+		
+		final ByteArrayHashMap<DHTTransportContact>	id_map = new ByteArrayHashMap<DHTTransportContact>();
+
+		List<DHTTransportContact> all_contacts = control.getClosestContactsList( my_id, router.getK()*3, true );
+				
+		for ( DHTTransportContact contact: all_contacts ){
+			
+			id_map.put( contact.getID(), contact );
+		}
+		
+		byte[]	max_key 	= my_id;
+		byte[]	max_dist	= null;
+		
+		final List<HashWrapper> applicable_keys = new ArrayList<HashWrapper>();
+		
+		try{
+			this_mon.enter();
+			
+			long	now = SystemTime.getMonotonousTime();
+			
+			Iterator<SurveyContactState> s_it = survey_state.values().iterator();
+			
+			while( s_it.hasNext()){
+				
+				if ( s_it.next().timeout( now )){
+					
+					s_it.remove();
+				}
+			}
+			
+			Iterator<DHTDBMapping>	it = stored_values.values().iterator();
+						
+			Set<HashWrapper>	existing_times = new HashSet<HashWrapper>( survey_mapping_times.keySet());
+			
+			while( it.hasNext()){
+				
+				DHTDBMapping	mapping = it.next();
+					
+				HashWrapper hw = mapping.getKey();
+				
+				if ( existing_times.size() > 0 ){
+				
+					existing_times.remove( hw );
+				}
+				
+				if ( !applyRF( mapping )){
+						
+					continue;
+				}
+					
+				applicable_keys.add( hw );
+				
+				byte[] key = hw.getBytes();
+				
+				/*
+				List<DHTTransportContact>	contacts = control.getClosestKContactsList( key, true );
+
+				for ( DHTTransportContact c: contacts ){
+					
+					id_map.put( c.getID(), c );
+				}
+				*/
+								
+				byte[] distance = control.computeDistance( my_id, key );
+				
+				if ( max_dist == null || control.compareDistances( distance, max_dist  ) > 0 ){
+					
+					max_dist	= distance;
+					max_key 	= key;
+				}
+			}
+			
+				// remove dead mappings
+			
+			for ( HashWrapper hw: existing_times ){
+				
+				survey_mapping_times.remove( hw );
+			}
+			
+			logger.log( "Survey starts: state size=" + survey_state.size() + ", all keys=" + stored_values.size() + ", applicable keys=" + applicable_keys.size());
+
+		}finally{
+			
+			this_mon.exit();
+		}
+		
+		if ( DEBUG_SURVEY ){
+			System.out.println( "    max_key=" + ByteFormatter.encodeString( max_key ) + ", dist=" + ByteFormatter.encodeString( max_dist ) + ", initial_contacts=" + id_map.size());
+		}
+		
+		if ( max_key == my_id ){
+			
+			logger.log( "Survey complete - no applicable values" );
+			
+			return;
+		}
+						
+			// obscure key so we don't leak any keys
+		
+		byte[]	obscured_key = control.getObfuscatedKey( max_key );
+		
+		final int[]	requery_count = { 0 };
+		
+		final boolean[]	processing = { false };
+		
+		try{
+			survey_in_progress = true;
+		
+			control.lookupEncoded(
+				obscured_key,
+				"Neighbourhood survey: basic",
+				0,
+				true,
+				new DHTOperationAdapter()
+				{
+					private List<DHTTransportContact> contacts = new ArrayList<DHTTransportContact>();
+					
+					private boolean	survey_complete;
+					
+					public void
+					found(
+						DHTTransportContact	contact,
+						boolean				is_closest )
+					{
+						if ( is_closest ){
+							
+							synchronized( contacts ){
+								
+								if ( !survey_complete ){
+									
+									contacts.add( contact );
+								}
+							}
+						}
+					}
+					
+					public void
+					complete(
+						boolean				timeout )
+					{
+						boolean	requeried = false;
+						
+						try{
+							int	hits	= 0;
+							int	misses	= 0;
+							
+								// find the closest miss to us and recursively search
+							
+							byte[]	min_dist 	= null;
+							byte[]	min_id		= null;
+							
+							synchronized( contacts ){
+								
+								for ( DHTTransportContact c: contacts ){
+									
+									byte[]	id = c.getID();
+									
+									if ( id_map.containsKey( id )){
+										
+										hits++;
+										
+									}else{
+										
+										misses++;
+										
+										if ( id_map.size() >= MAX_SURVEY_SIZE ){
+											
+											log( "Max survery size exceeded" );
+											
+											break;
+										}
+										
+										id_map.put( id, c );
+										
+										byte[] distance = control.computeDistance( my_id, id );
+										
+										if ( min_dist == null || control.compareDistances( distance, min_dist  ) < 0 ){
+								
+											min_dist	= distance;
+											min_id		= id;
+										}
+									}
+								}
+								
+								contacts.clear();
+							}
+							
+								// if significant misses then re-query
+							
+							if ( misses > 0 && misses*100/(hits+misses) >= 25 && id_map.size()< MAX_SURVEY_SIZE ){
+								
+								if ( requery_count[0]++ < 5 ){
+									
+									if ( DEBUG_SURVEY ){
+										System.out.println( "requery at " + ByteFormatter.encodeString( min_id )); 
+									}
+									
+										// don't need to obscure here as its a node-id
+									
+									control.lookupEncoded( 
+										min_id,
+										"Neighbourhood survey: level=" + requery_count[0],
+										0, 
+										true,
+										this );
+									
+									requeried = true;
+									
+								}else{
+									
+									if ( DEBUG_SURVEY ){
+										System.out.println( "requery limit exceeded" );
+									}
+								}
+							}else{
+								
+								if ( DEBUG_SURVEY ){
+									System.out.println( "super-neighbourhood=" + id_map.size() + " (hits=" + hits + ", misses=" + misses + ", level=" + requery_count[0] + ")" );
+								}
+							}
+						}finally{
+							
+							if ( !requeried ){
+								
+								synchronized( contacts ){
+
+									survey_complete = true;
+								}
+								
+								if ( DEBUG_SURVEY ){
+									System.out.println( "survey complete: nodes=" + id_map.size());
+								}
+																			
+								processSurvey( my_id, applicable_keys, id_map );
+								
+								processing[0] = true;
+							}
+						}
+					}
+				});
+			
+		}catch( Throwable e ){
+			
+			if ( !processing[0] ){
+			
+				logger.log( "Survey complete - no applicable nodes" );
+
+				survey_in_progress = false;
+			}
+		}
+	}
+	
+	protected void
+	processSurvey(
+		byte[]									survey_my_id,
+		List<HashWrapper>						applicable_keys,
+		ByteArrayHashMap<DHTTransportContact>	survey )
+	{
+		boolean went_async = false;
+		
+		try{
+			byte[][]	node_ids = new byte[survey.size()][];
+			
+			int	pos = 0;
+						
+			for ( byte[] id: survey.keys()){
+				
+				node_ids[pos++] = id;
+			}
+				
+			ByteArrayHashMap<List<DHTDBMapping>>	value_map = new ByteArrayHashMap<List<DHTDBMapping>>();
+			
+			Map<DHTTransportContact,ByteArrayHashMap<List<DHTDBMapping>>> request_map = new HashMap<DHTTransportContact, ByteArrayHashMap<List<DHTDBMapping>>>();
+					
+			Map<DHTDBMapping,List<DHTTransportContact>>	mapping_to_node_map = new HashMap<DHTDBMapping, List<DHTTransportContact>>();
+			
+			int max_nodes = Math.min( node_ids.length, router.getK());
+			
+			try{
+				this_mon.enter();
+							
+				Iterator<HashWrapper>	it = applicable_keys.iterator();
+				
+				int	value_count = 0;
+				
+				while( it.hasNext()){
+					
+					DHTDBMapping	mapping = stored_values.get( it.next());
+		
+					if ( mapping == null ){
+							
+						continue;
+					}
+					
+					value_count++;
+					
+					final byte[] key = mapping.getKey().getBytes();
+					
+						// find closest nodes to this key in order to asses availability
+					
+					Arrays.sort(
+						node_ids,
+						new Comparator<byte[]>()
+						{
+							public int 
+							compare(
+								byte[] o1, 
+								byte[] o2 ) 
+							{
+								return( control.computeAndCompareDistances( o1, o2, key ));
+							}
+						});
+					
+					boolean	found_myself = false;
+					
+					for ( int i=0;i<max_nodes;i++ ){
+						
+						byte[]	id = node_ids[i];
+
+						if ( Arrays.equals( survey_my_id, id )){
+							
+							found_myself = true;
+							
+							break;
+						}
+					}
+					
+						// if we're not in the closest set to this key then ignore it
+					
+					if ( !found_myself ){
+						
+						if ( DEBUG_SURVEY ){
+							System.out.println( "we're not in closest set for " + ByteFormatter.encodeString( key ) + " - ignoring" );
+						}
+						
+						continue;
+					}
+					
+					List<DHTTransportContact>	node_list = new ArrayList<DHTTransportContact>(max_nodes);
+					
+					mapping_to_node_map.put( mapping, node_list );
+					
+					for ( int i=0;i<max_nodes;i++ ){
+						
+						byte[]	id = node_ids[i];
+						
+							// remove ourselves from the equation here as we don't want to end
+							// up querying ourselves and we account for the replica we have later
+							// on
+						
+						if ( Arrays.equals( survey_my_id, id )){
+							
+							continue;
+						}
+						
+						List<DHTDBMapping> list = value_map.get( id );
+						
+						if ( list == null ){
+							
+							list = new ArrayList<DHTDBMapping>();
+							
+							value_map.put( id, list );
+						}
+						
+						list.add( mapping );
+						
+						node_list.add( survey.get( id ));
+					}
+				}
+				
+				if ( DEBUG_SURVEY ){
+					System.out.println( "Total values: " + value_count );
+				}
+				
+					// build a list of requests to send to nodes to check their replicas
+				
+				for ( byte[] id: node_ids ){
+										
+					final int MAX_PREFIX_TEST = 3;
+									
+					List<DHTDBMapping> all_entries = value_map.remove( id );
+					
+					ByteArrayHashMap<List<DHTDBMapping>> prefix_map = new ByteArrayHashMap<List<DHTDBMapping>>();
+
+					if ( all_entries != null ){
+						
+						prefix_map.put( new byte[0], all_entries );
+						
+						for (int i=0;i<MAX_PREFIX_TEST;i++){
+						
+							List<byte[]> prefixes = prefix_map.keys();
+							
+							for ( byte[] prefix: prefixes ){
+								
+								if ( prefix.length == i ){
+	
+									List<DHTDBMapping> list = prefix_map.get( prefix );
+	
+									if ( list.size() < 2 ){
+										
+										continue;
+									}
+									
+									ByteArrayHashMap<List<DHTDBMapping>> temp_map = new ByteArrayHashMap<List<DHTDBMapping>>();
+									
+									for ( DHTDBMapping mapping: list ){
+										
+										byte[] key = mapping.getKey().getBytes();
+										
+										byte[] sub_prefix = new byte[ i+1 ];
+										
+										System.arraycopy( key, 0, sub_prefix, 0, i+1 );
+	
+										List<DHTDBMapping> entries = temp_map.get( sub_prefix );
+										
+										if ( entries == null ){
+											
+											entries = new ArrayList<DHTDBMapping>();
+											
+											temp_map.put( sub_prefix, entries );
+										}
+										
+										entries.add( mapping );
+									}
+									
+									List<DHTDBMapping> new_list = new ArrayList<DHTDBMapping>( list.size());
+	
+									List<byte[]> temp_keys = temp_map.keys();
+									
+									for ( byte[] k: temp_keys ){
+										
+										List<DHTDBMapping> entries = temp_map.get( k );
+										
+										int	num	= entries.size();
+										
+											// prefix spread over multiple entries so ignore and just count suffix cost
+											
+										int outer_cost 	= num * ( QUERY_STORE_REQUEST_ENTRY_SIZE - i );
+										
+											// include new prefix, one byte prefix len, 2 bytes num-suffixes, then suffixes
+											// yes, this code should be elsewhere, but whatever
+										
+										int inner_cost	= i+4 + num * (QUERY_STORE_REQUEST_ENTRY_SIZE - i - 1 );
+										
+										if ( inner_cost < outer_cost ){
+											
+											prefix_map.put( k, entries );
+											
+										}else{
+											
+											new_list.addAll( entries );
+										}
+									}
+									
+									if ( new_list.size() == 0 ){
+										
+										prefix_map.remove( prefix );
+										
+									}else{
+										
+										prefix_map.put( prefix, new_list );
+									}
+								}
+							}
+						}
+					
+						String str = "";
+						
+						int encoded_size = 1;	// header size 
+							
+						List<byte[]> prefixes = prefix_map.keys();
+						
+						for ( byte[] prefix: prefixes ){
+							
+							encoded_size += 3 + prefix.length;
+							
+							List<DHTDBMapping> entries = prefix_map.get( prefix );
+							
+							encoded_size += ( QUERY_STORE_REQUEST_ENTRY_SIZE - prefix.length ) * entries.size();
+							
+							str += (str.length()==0?"":", ")+ ByteFormatter.encodeString( prefix ) + "->" + entries.size();
+						}
+						
+						if ( DEBUG_SURVEY ){
+							System.out.println( "node " + ByteFormatter.encodeString( id ) + " -> " + (all_entries==null?0:all_entries.size()) + ", encoded=" + encoded_size + ", prefix=" + str );
+						}
+						
+						if ( prefixes.size() > 0 ){
+							
+							request_map.put( survey.get( id ), prefix_map );
+						}
+					}
+				}
+			}finally{
+				
+				this_mon.exit();
+			}
+						
+			LinkedList<Map.Entry<DHTTransportContact,ByteArrayHashMap<List<DHTDBMapping>>>> to_do = new LinkedList<Map.Entry<DHTTransportContact,ByteArrayHashMap<List<DHTDBMapping>>>>( request_map.entrySet());
+				
+			Map<DHTTransportContact,Object[]>	replies = new HashMap<DHTTransportContact,Object[]>();
+			
+			for ( int i=0;i<Math.min(3,to_do.size());i++ ){
+			
+				went_async = true;
+				
+				doQuery( survey_my_id, request_map.size(), mapping_to_node_map, to_do, replies, null, null, null );
+			}
+				
+		}finally{
+			
+			if ( !went_async ){
+			
+				logger.log( "Survey complete - no applicable queries" );
+
+				survey_in_progress = false;
+			}
+		}
+	}
+	
+	protected boolean
+	applyRF(
+		DHTDBMapping	mapping )
+	{
+		if ( mapping.getDiversificationType() != DHT.DT_NONE ){
+			
+			return( false );
+		}
+						
+		if ( SURVEY_ONLY_RF_KEYS ){
+
+			Iterator<DHTDBValueImpl>	it2 = mapping.getValues();
+		
+			if ( !it2.hasNext()){
+				
+				return( false );
+			}
+			
+			int	min_period = Integer.MAX_VALUE;
+			
+			long	min_create = Long.MAX_VALUE;
+			
+			while( it2.hasNext()){
+	
+				DHTDBValueImpl value = it2.next();
+				
+				byte rep_fact = value.getReplicationFactor();
+				
+				if ( rep_fact == DHT.REP_FACT_DEFAULT || rep_fact == 0 ){
+	
+					return( false );
+				}
+				
+				int hours = value.getReplicationFrequencyHours()&0xff;
+				
+				if ( hours < min_period ){
+					
+					min_period = hours;
+				}
+				
+				min_create = Math.min( min_create, value.getCreationTime());
+			}
+			
+			if ( min_period > 0 ){
+				
+				HashWrapper hw = mapping.getKey();
+				
+				Long	next_time = survey_mapping_times.get( hw );
+				
+				long now = SystemTime.getMonotonousTime();
+				
+				if ( next_time != null && next_time > now ){
+					
+					return( false );
+				}
+				
+				long	period		= min_period*60*60*1000;
+				
+				long	offset_time = ( SystemTime.getCurrentTime() - min_create ) % period;
+				
+				long	rand		= RandomUtils.nextInt( 30*60*1000 ) - 15*60*1000;
+				
+				long	new_next_time = now - offset_time + period + rand;
+				
+				if ( new_next_time < now + 30*60*1000 ){
+					
+					new_next_time += period;
+				}
+				
+				if ( DEBUG_SURVEY ){
+					System.out.println( "allocated next time with value relative " + (new_next_time-now) + ": period=" + period + ", offset=" + offset_time + ", rand=" + rand );
+				}
+				
+				survey_mapping_times.put( hw, new_next_time );
+				
+				if ( next_time == null ){
+					
+					return( false );
+				}
+			}
+		}
+		
+		return( true );
+	}
+	
+	protected void
+	doQuery(
+		final byte[]			survey_my_id,
+		final int				total,
+		final Map<DHTDBMapping,List<DHTTransportContact>>										mapping_to_node_map,
+		final LinkedList<Map.Entry<DHTTransportContact,ByteArrayHashMap<List<DHTDBMapping>>>>	to_do,
+		final Map<DHTTransportContact,Object[]>													replies,
+		DHTTransportContact		done_contact,
+		List<DHTDBMapping>		done_mappings,
+		List<byte[]>			done_reply )
+	{
+		Map.Entry<DHTTransportContact,ByteArrayHashMap<List<DHTDBMapping>>>	entry;
+		
+		synchronized( to_do ){
+			
+			if ( done_contact != null ){
+				
+				replies.put( done_contact, new Object[]{ done_mappings, done_reply });
+			}
+			
+			if ( to_do.size() == 0 ){
+			
+				if ( replies.size() == total ){
+					
+					queriesComplete( survey_my_id, mapping_to_node_map, replies );
+				}
+				
+				return;
+			}
+			
+			entry = to_do.removeFirst();
+		}
+		
+		DHTTransportContact contact = entry.getKey();
+		
+		boolean	handled = false;
+		
+		try{
+			if ( contact.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL3 ){
+			
+				if ( DEBUG_SURVEY ){
+					System.out.println( "Hitting " + contact.getString());
+				}
+				
+				final List<DHTDBMapping>	mapping_list = new ArrayList<DHTDBMapping>();
+				
+				ByteArrayHashMap<List<DHTDBMapping>>	map = entry.getValue();
+				
+				List<byte[]> prefixes = map.keys();
+	
+				List<Object[]> encoded = new ArrayList<Object[]>( prefixes.size() );					
+				
+				try{
+					this_mon.enter();
+			
+					SurveyContactState contact_state = survey_state.get( new HashWrapper( contact.getID()));
+					
+					for ( byte[] prefix: prefixes ){
+						
+						int	prefix_len = prefix.length;
+						int	suffix_len = QUERY_STORE_REQUEST_ENTRY_SIZE - prefix_len;
+						
+						List<DHTDBMapping> mappings = map.get( prefix );
+						
+						List<byte[]> l = new ArrayList<byte[]>( mappings.size());
+						
+						encoded.add( new Object[]{ prefix, l });
+						
+							// remove entries that we know the contact already has
+							// and then add them back in in the query-reply. note that we
+							// still need to hit the contact if we end up with no values to
+							// query as need to ascertain liveness. We might want to wait until,
+							// say, 2 subsequent fails before treating contact as dead
+						
+						for ( DHTDBMapping m: mappings ){
+						
+							if ( contact_state != null ){
+								
+								if ( contact_state.testMapping(m)){
+							
+									if ( DEBUG_SURVEY ){
+										System.out.println( "    skipping " + ByteFormatter.encodeString( m.getKey().getBytes()) + " as contact already has" );
+									}
+									
+									continue;
+								}
+							}
+							
+							mapping_list.add( m );
+							
+							byte[]	k = m.getKey().getBytes();
+							
+							byte[]	suffix = new byte[ suffix_len ];
+							
+							System.arraycopy( k, prefix_len, suffix, 0, suffix_len );
+							
+							l.add( suffix );
+						}
+					}
+				
+					if ( contact.getID().equals( survey_my_id )){
+						
+						Debug.out( "inconsistent - we shouldn't query ourselves!" );
+					}
+					
+					contact.sendQueryStore(
+						new DHTTransportReplyHandlerAdapter()
+						{
+							public void
+							queryStoreReply(
+								DHTTransportContact contact,
+								List<byte[]>		response )
+							{
+								try{
+									if ( DEBUG_SURVEY ){
+										System.out.println( "response " + response.size());
+										
+										for (int i=0;i<response.size();i++){
+											
+											System.out.println( "    " + ByteFormatter.encodeString( response.get(i)));
+										}
+									}
+								}finally{
+								
+									doQuery( survey_my_id, total, mapping_to_node_map, to_do, replies, contact, mapping_list, response );
+								}
+							}
+							
+							public void
+							failed(
+								DHTTransportContact 	contact,
+								Throwable				error )
+							{
+								try{
+									if ( DEBUG_SURVEY ){
+										System.out.println( "Failed: " + Debug.getNestedExceptionMessage( error ));
+									}
+								}finally{
+									
+									doQuery( survey_my_id, total, mapping_to_node_map, to_do, replies, contact, mapping_list, null );
+								}
+							}
+						}, QUERY_STORE_REQUEST_ENTRY_SIZE, encoded );
+					
+					handled = true;
+					
+				}finally{
+					
+					this_mon.exit();
+				}
+			}else{
+				if ( DEBUG_SURVEY ){
+					System.out.println( "Not hitting " + contact.getString());
+				}
+			}
+		}finally{
+			
+			if ( !handled ){
+					
+				final List<DHTDBMapping>	mapping_list = new ArrayList<DHTDBMapping>();
+				
+				ByteArrayHashMap<List<DHTDBMapping>>	map = entry.getValue();
+				
+				List<byte[]> prefixes = map.keys();
+				
+				for ( byte[] prefix: prefixes ){
+												
+					mapping_list.addAll( map.get( prefix ));
+				}
+				
+				doQuery( survey_my_id, total, mapping_to_node_map, to_do, replies, contact, mapping_list, null );
+			}
+		}
+	}
+	
+	protected void
+	queriesComplete(
+		byte[]											survey_my_id,
+		Map<DHTDBMapping,List<DHTTransportContact>>		mapping_to_node_map,
+		Map<DHTTransportContact,Object[]>				replies )
+	{
+		Map<SurveyContactState,List<DHTDBMapping>>	store_ops = new HashMap<SurveyContactState, List<DHTDBMapping>>();
+
+		try{
+			this_mon.enter();
+			
+			if ( !Arrays.equals( survey_my_id, router.getID())){
+				
+				logger.log( "Survey abandoned - router changed" );
+
+				return;
+			}
+			
+			if ( DEBUG_SURVEY ){
+				System.out.println( "Queries complete (replies=" + replies.size() + ")" );
+			}
+					
+			Map<DHTDBMapping,int[]>	totals = new HashMap<DHTDBMapping, int[]>();
+			
+			for ( Map.Entry<DHTTransportContact,Object[]> entry: replies.entrySet()){
+				
+				DHTTransportContact	contact = entry.getKey();
+				
+				HashWrapper hw = new HashWrapper( contact.getID());
+				
+				SurveyContactState	contact_state = survey_state.get( hw );
+				
+				if ( contact_state != null ){
+					
+					contact_state.updateContactDetails( contact );
+					
+				}else{
+					
+					contact_state = new SurveyContactState( contact );
+					
+					survey_state.put( hw, contact_state );
+				}
+				
+				contact_state.updateUseTime();
+				
+				Object[]			temp	= entry.getValue();
+				
+				List<DHTDBMapping>	mappings 	= (List<DHTDBMapping>)temp[0];
+				List<byte[]>		reply		= (List<byte[]>)temp[1];
+				
+				if ( reply == null ){
+										
+					contact_state.contactFailed();
+					
+				}else{
+					
+					contact_state.contactOK();
+
+					if ( mappings.size() != reply.size()){
+						
+						Debug.out( "Inconsistent: mappings=" + mappings.size() + ", reply=" + reply.size());
+						
+						continue;
+					}
+					
+					Iterator<DHTDBMapping>	it1 = mappings.iterator();
+					Iterator<byte[]>		it2 = reply.iterator();
+					
+					while( it1.hasNext()){
+						
+						DHTDBMapping	mapping = it1.next();
+						byte[]			rep		= it2.next();
+						
+						if ( rep == null ){
+							
+							contact_state.removeMapping( mapping );
+							
+						}else{
+							
+								// must match against our short-key mapping for consistency
+							
+							DHTDBMapping mapping_to_check = stored_values_prefix_map.get( mapping.getShortKey());
+							
+							if ( mapping_to_check == null ){
+								
+								// deleted
+								
+							}else{
+								
+								byte[] k = mapping_to_check.getKey().getBytes();
+		
+								int	rep_len = rep.length;
+								
+								if ( rep_len < 2 || rep_len >= k.length ){
+									
+									Debug.out( "Invalid rep_len: " + rep_len );
+									
+									continue;
+								}
+								
+								boolean	match = true;
+								
+								int	offset = k.length-rep_len;
+								
+								for (int i=0;i<rep_len;i++){
+									
+									if ( rep[i] != k[i+offset] ){
+										
+										match = false;
+										
+										break;
+									}
+								}
+								
+								if ( match ){
+																
+									contact_state.addMapping( mapping );
+									
+								}else{
+									
+									contact_state.removeMapping( mapping );
+								}
+							}
+						}
+					}
+					
+					Set<DHTDBMapping> contact_mappings = contact_state.getMappings();
+					
+					for ( DHTDBMapping m: contact_mappings ){
+						
+						int[] t = totals.get( m );
+						
+						if ( t == null ){
+							
+							t = new int[]{ 2 };		// one for local node + 1 for them
+							
+							totals.put( m, t );
+							
+						}else{
+							
+							t[0]++;
+						}
+					}
+				}
+			}
+						
+			for (Map.Entry<DHTDBMapping,List<DHTTransportContact>> entry: mapping_to_node_map.entrySet()){
+				
+				DHTDBMapping				mapping 	= entry.getKey();
+				List<DHTTransportContact>	contacts 	= entry.getValue();
+				
+				int[]	t = totals.get( mapping );
+				
+				int	copies;
+				
+				if ( t == null ){
+					
+					copies = 1;		// us!
+					
+				}else{
+					
+					copies = t[0];
+				}
+								
+				Iterator<DHTDBValueImpl> values = mapping.getValues();
+				
+				if ( values.hasNext()){
+				
+					int	max_replication_factor = -1;
+				
+					while( values.hasNext()){
+						
+						DHTDBValueImpl value = values.next();
+						
+						int	rf = value.getReplicationFactor();
+						
+						if ( rf > max_replication_factor ){
+							
+							max_replication_factor = rf;
+						}
+					}
+					
+					if ( max_replication_factor == 0 ){
+						
+						continue;
+					}
+					
+					if ( max_replication_factor > router.getK()){
+						
+						max_replication_factor = router.getK();
+					}
+					
+					if ( copies < max_replication_factor ){
+						
+						int	required = max_replication_factor - copies;
+						
+						List<SurveyContactState> potential_targets = new ArrayList<SurveyContactState>();
+						
+						List<byte[]>	addresses = new ArrayList<byte[]>( contacts.size());
+						
+						for ( DHTTransportContact c: contacts ){
+						
+							if ( c.getProtocolVersion() < DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL3 ){
+								
+								continue;
+							}
+							
+							addresses.add( c.getAddress().getAddress().getAddress());
+							
+							SurveyContactState	contact_state = survey_state.get( new HashWrapper( c.getID()));
+							
+							if ( contact_state != null && !contact_state.testMapping( mapping )){
+								
+								potential_targets.add( contact_state );
+							}
+						}
+						
+						Set<HashWrapper>	bad_addresses = new HashSet<HashWrapper>();
+						
+						for ( byte[] a1: addresses ){
+							
+							for ( byte[] a2: addresses ){
+								
+									// ignore ipv6 for the moment...
+								
+								if ( a1 == a2 || a1.length != a2.length || a1.length != 4 ){
+									
+									continue;
+								}
+								
+									// ignore common /16 s
+								
+								if ( a1[0] == a2[0] && a1[1] == a2[1] ){
+									
+									log( "/16 match on " + ByteFormatter.encodeString( a1 ) + "/" + ByteFormatter.encodeString( a2 ));
+									
+									bad_addresses.add( new HashWrapper( a1 ));
+									bad_addresses.add( new HashWrapper( a2 ));
+								}
+							}
+						}
+						
+						final byte[] key = mapping.getKey().getBytes();
+						
+						Collections.sort(
+							potential_targets,
+							new Comparator<SurveyContactState>()
+							{
+								public int 
+								compare(
+									SurveyContactState o1,
+									SurveyContactState o2) 
+								{
+									boolean o1_bad = o1.getConsecFails() >= 2;
+									boolean o2_bad = o2.getConsecFails() >= 2;
+									
+									if ( o1_bad == o2_bad ){
+										
+											// switch from age based to closest as per Roxana's advice
+										
+										if ( false ){
+											
+											long res = o2.getCreationTime() - o1.getCreationTime();
+								
+											if ( res < 0 ){
+												
+												return( -1 );
+												
+											}else if ( res > 0 ){
+												
+												return( 1 );
+												
+											}else{
+												
+												return( 0 );
+											}
+										}else{
+											
+											return(
+												control.computeAndCompareDistances(
+														o1.getContact().getID(),
+														o2.getContact().getID(),
+														key ));
+										}
+									}else{
+								
+										if ( o1_bad ){
+											
+											return( 1 );
+											
+										}else{
+											
+											return( -1 );
+										}
+									}
+								}
+							});
+						
+						int	avail = Math.min( required, potential_targets.size());
+						
+						for (int i=0;i<avail;i++){
+							
+							SurveyContactState target = potential_targets.get( i );
+							
+							if ( 	bad_addresses.size() > 0 && 
+									bad_addresses.contains( new HashWrapper( target.getContact().getAddress().getAddress().getAddress()))){
+								
+									// make it look like this target has the mapping as we don't want to store it there but we want to treat it as
+									// if it has it, effectively reducing availability but not skewing storage in favour of potentially malicious nodes
+								
+								target.addMapping( mapping );
+								
+							}else{
+							
+								List<DHTDBMapping> m = store_ops.get( target );
+								
+								if ( m == null ){
+									
+									m = new ArrayList<DHTDBMapping>();
+									
+									store_ops.put( target, m );
+								}
+								
+								m.add( mapping );
+							}
+						}
+					}
+				}
+			}
+		}finally{
+			
+			this_mon.exit();
+			
+			survey_in_progress = false;
+		}
+		
+		logger.log( "Survey complete - " + store_ops.size() + " store ops" );
+
+		if ( DEBUG_SURVEY ){
+			System.out.println( "Store ops: " + store_ops.size());
+		}
+		
+		for ( Map.Entry<SurveyContactState,List<DHTDBMapping>> store_op: store_ops.entrySet()){
+			
+			final SurveyContactState 	contact = store_op.getKey();
+			final List<DHTDBMapping>	keys	= store_op.getValue();
+			
+			final byte[][]				store_keys 		= new byte[keys.size()][];
+			final DHTTransportValue[][]	store_values 	= new DHTTransportValue[store_keys.length][];
+				
+			for (int i=0;i<store_keys.length;i++){
+			
+				DHTDBMapping	mapping = keys.get(i);
+			
+				store_keys[i] = mapping.getKey().getBytes();
+					
+				List<DHTTransportValue> v = new ArrayList<DHTTransportValue>();
+				
+				Iterator<DHTDBValueImpl> it = mapping.getValues();
+				
+				while( it.hasNext()){
+					
+					DHTDBValueImpl value = it.next();
+					
+					if ( !value.isLocal()){
+						
+						v.add( value.getValueForRelay(local_contact));
+					}
+				}
+				
+				store_values[i] = v.toArray( new DHTTransportValue[v.size()]);
+			}
+				
+			final DHTTransportContact d_contact = contact.getContact();
+			
+			final Runnable	store_exec = 
+				new Runnable()
+				{
+					public void
+					run()
+					{
+						if ( DEBUG_SURVEY ){
+							System.out.println( "Storing " + keys.size() + " on " + d_contact.getString() + " - rand=" + d_contact.getRandomID());
+						}
+						
+						control.putDirectEncodedKeys( 
+								store_keys, 
+								"Replication forward",
+								store_values,
+								d_contact,
+								new DHTOperationAdapter()
+								{
+									public void
+									complete(
+										boolean				timeout )
+									{
+										try{
+											this_mon.enter();
+			
+											if ( timeout ){
+												
+												contact.contactFailed();
+												
+											}else{
+												
+												contact.contactOK();
+												
+												for ( DHTDBMapping m: keys ){
+													
+													contact.addMapping( m );
+												}
+											}
+										}finally{
+											
+											this_mon.exit();
+										}
+									}
+								});
+					}
+				};
+				
+			if ( d_contact.getRandomID() == 0 ){
+				
+				d_contact.sendFindNode(
+						new DHTTransportReplyHandlerAdapter()
+						{
+							public void
+							findNodeReply(
+								DHTTransportContact 	_contact,
+								DHTTransportContact[]	_contacts )
+							{	
+								store_exec.run();
+							}
+					
+							public void
+							failed(
+								DHTTransportContact 	_contact,
+								Throwable				_error )
+							{
+								try{
+									this_mon.enter();
+										
+									contact.contactFailed();
+										
+								}finally{
+									
+									this_mon.exit();
+								}
+							}
+						},
+						d_contact.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_ANTI_SPOOF2?new byte[0]:new byte[20] );
+			}else{
+				
+				store_exec.run();
+			}
+		}
+	}
+	
+	
+	
+	public DHTTransportQueryStoreReply
+	queryStore(
+		DHTTransportContact 		originating_contact, 
+		int							header_len,
+		List<Object[]>				keys )
+	{
+		final List<byte[]> reply = new ArrayList<byte[]>();
+		
+		try{
+			this_mon.enter();
+			
+			SurveyContactState	existing_state = survey_state.get( new HashWrapper( originating_contact.getID()));
+			
+			if ( existing_state != null ){
+				
+				existing_state.updateContactDetails( originating_contact );
+			}
+			
+			for (Object[] entry: keys ){
+				
+				byte[]			prefix 		= (byte[])entry[0];
+				List<byte[]>	suffixes 	= (List<byte[]>)entry[1];
+				
+				byte[]	header = new byte[header_len];
+				
+				int		prefix_len	= prefix.length;
+				int		suffix_len	= header_len - prefix_len;
+				
+				System.arraycopy( prefix, 0, header, 0, prefix_len );
+				
+				for ( byte[] suffix: suffixes ){
+					
+					System.arraycopy( suffix, 0, header, prefix_len, suffix_len );
+					
+					DHTDBMapping mapping = stored_values_prefix_map.get( new DHTDBMapping.ShortHash( header ));
+					
+					if ( mapping == null ){
+					
+						reply.add( null );
+						
+					}else{
+						
+						if ( existing_state != null ){
+							
+							existing_state.addMapping( mapping );
+						}
+						
+						byte[] k = mapping.getKey().getBytes();
+						
+						byte[] r = new byte[QUERY_STORE_REPLY_ENTRY_SIZE];
+						
+						System.arraycopy( k, k.length-QUERY_STORE_REPLY_ENTRY_SIZE, r, 0, QUERY_STORE_REPLY_ENTRY_SIZE );
+						
+						reply.add( r );
+					}
+				}
+			}
+			
+			return( 
+				new DHTTransportQueryStoreReply()
+				{
+					public int
+					getHeaderSize()
+					{
+						return( QUERY_STORE_REPLY_ENTRY_SIZE );
+					}
+					
+					public List<byte[]>
+					getEntries()
+					{
+						return( reply );
+					}
+				});
+			
+		}finally{
+			
+			this_mon.exit();
+		}
+	}
+	
 	public void
 	print(
 		boolean	full )
 	{
-		Map	count = new TreeMap();
+		Map<Integer,Object[]>	count = new TreeMap<Integer,Object[]>();
 		
 		try{
 			this_mon.enter();
@@ -1464,17 +2930,23 @@ DHTDBImpl
 				return;
 			}
 			
-			Iterator	it = stored_values.entrySet().iterator();
+			Iterator<Map.Entry<HashWrapper,DHTDBMapping>>	it1 = stored_values.entrySet().iterator();
 			
-			while( it.hasNext()){
+			// ByteArrayHashMap<Integer> blah = new ByteArrayHashMap<Integer>();
+			
+			while( it1.hasNext()){
 						
-				Map.Entry		entry = (Map.Entry)it.next();
+				Map.Entry<HashWrapper,DHTDBMapping>		entry = it1.next();
 				
-				HashWrapper		value_key	= (HashWrapper)entry.getKey();
+				HashWrapper		value_key	= entry.getKey();
 				
-				DHTDBMapping	mapping = (DHTDBMapping)entry.getValue();
+				DHTDBMapping	mapping 	= entry.getValue();
 				
-				// mapping.print();
+				/*
+				if ( mapping.getIndirectSize() > 1000 ){
+					mapping.print();
+				}
+				*/
 				
 				DHTDBValue[]	values = mapping.get(null,0,(byte)0);
 					
@@ -1482,6 +2954,18 @@ DHTDBImpl
 					
 					DHTDBValue	value = values[i];
 					
+					/*
+					byte[] v = value.getValue();
+					
+					Integer y = blah.get( v );
+					
+					if ( y == null ){
+						blah.put( v, 1 );
+					}else{
+						blah.put( v, y+1 );
+					}
+					*/
+					
 					Integer key = new Integer( value.isLocal()?0:1);
 					
 					Object[]	data = (Object[])count.get( key );
@@ -1509,29 +2993,47 @@ DHTDBImpl
 				}
 			}
 			
-			it = count.keySet().iterator();
+			/*
+			long	total_dup = 0;
 			
-			while( it.hasNext()){
+			for ( byte[] k: blah.keys()){
+				
+				int c = blah.get( k );
+				
+				if ( c > 1 ){
+					
+					total_dup += ( c * k.length );
+					
+					System.out.println( "Dup: " + new String(k) + " -> " + c );
+				}
+			}
+			
+			System.out.println( "Total dup: " + total_dup );
+			*/
+			
+			Iterator<Integer> it2 = count.keySet().iterator();
+			
+			while( it2.hasNext()){
 				
-				Integer	k = (Integer)it.next();
+				Integer	k = it2.next();
 				
 				Object[]	data = (Object[])count.get(k);
 				
 				logger.log( "    " + k + " -> " + data[0] + " entries" ); // ": " + data[1]);
 			}
 			
-			it = stored_values.entrySet().iterator();
+			Iterator<Map.Entry<HashWrapper,DHTDBMapping>> it3 = stored_values.entrySet().iterator();
 			
 			String	str 		= "    ";
 			int		str_entries	= 0;
 			
-			while( it.hasNext()){
+			while( it3.hasNext()){
 						
-				Map.Entry		entry = (Map.Entry)it.next();
+				Map.Entry<HashWrapper,DHTDBMapping>		entry = it3.next();
 				
-				HashWrapper		value_key	= (HashWrapper)entry.getKey();
+				HashWrapper		value_key	= entry.getKey();
 				
-				DHTDBMapping	mapping = (DHTDBMapping)entry.getValue();
+				DHTDBMapping	mapping 	= entry.getValue();
 				
 				if ( str_entries == 16 ){
 					
@@ -1579,7 +3081,7 @@ DHTDBImpl
 				try{
 					this_mon.enter();
 					
-					Iterator	it = stored_values.values().iterator();
+					Iterator<DHTDBMapping>	it = stored_values.values().iterator();
 						
 					boolean	overall_deleted = false;
 					
@@ -1587,7 +3089,7 @@ DHTDBImpl
 					
 					while( it.hasNext()){
 						
-						DHTDBMapping	mapping = (DHTDBMapping)it.next();
+						DHTDBMapping	mapping = it.next();
 						
 						boolean	deleted = false;
 						
@@ -1703,21 +3205,21 @@ DHTDBImpl
 			//Map		sender_map	= new HashMap();
 			//List	senders		= new ArrayList();
 			
-			Iterator	it = stored_values.values().iterator();
+			Iterator<DHTDBMapping>	it = stored_values.values().iterator();
 			
 			int	max_hits = 0;
 			
 			while( it.hasNext()){
 				
-				DHTDBMapping	mapping = (DHTDBMapping)it.next();
+				DHTDBMapping	mapping = it.next();
 
 				mapping.rebuildIPBloomFilter( false );
 				
-				Iterator	it2 = mapping.getDirectValues();
+				Iterator<DHTDBValueImpl>	it2 = mapping.getDirectValues();
 				
 				while( it2.hasNext()){
 					
-					DHTDBValueImpl	val = (DHTDBValueImpl)it2.next();
+					DHTDBValueImpl	val = it2.next();
 					
 					if ( !val.isLocal()){
 						
@@ -1782,7 +3284,7 @@ DHTDBImpl
 				*/
 			}
 			
-			logger.log( "Rebuilt global IP bloom filter, size = " + new_filter.getSize() + ", entries =" + new_filter.getEntryCount()+", max hits = " + max_hits );
+			logger.log( "Rebuilt global IP bloom filter, size=" + new_filter.getSize() + ", entries=" + new_filter.getEntryCount()+", max hits=" + max_hits );
 				
 			/*
 			senders = control.sortContactsByDistance( senders );
@@ -2062,6 +3564,7 @@ DHTDBImpl
 		
 		public byte[][]
 		createNewDiversification(
+			String				description,
 			DHTTransportContact	cause,
 			byte[]				key,
 			boolean				put_operation,
@@ -2069,7 +3572,7 @@ DHTDBImpl
 			boolean				exhaustive_get,
 			int					max_depth )
 		{
-			return( delegate.createNewDiversification( cause, key, put_operation, diversification_type, exhaustive_get, max_depth ));
+			return( delegate.createNewDiversification( description, cause, key, put_operation, diversification_type, exhaustive_get, max_depth ));
 		}
 		
 		public int
@@ -2135,4 +3638,142 @@ DHTDBImpl
 			return( delegate.getRemoteSizeDivCount());
 		}
 	}
+	
+	protected static class
+	SurveyContactState
+	{
+		private DHTTransportContact		contact;
+		
+		private long					creation_time	= SystemTime.getMonotonousTime();
+		private long					timeout			= creation_time + SURVEY_STATE_MAX_LIFE_TIMEOUT + RandomUtils.nextInt( SURVEY_STATE_MAX_LIFE_RAND );
+		
+		private long					last_used		= creation_time;
+		
+		private Set<DHTDBMapping>		mappings = new HashSet<DHTDBMapping>();
+		
+		private int	consec_fails;
+		
+		protected
+		SurveyContactState(
+			DHTTransportContact		c )
+		{
+			contact = c;
+			
+			log( "new" );
+		}
+		
+		protected boolean
+		timeout(
+			long	now )
+		{
+			 return( now - last_used > SURVEY_STATE_INACT_TIMEOUT || now > timeout );
+		}
+		
+		protected DHTTransportContact
+		getContact()
+		{
+			return( contact );
+		}
+		
+		protected long
+		getCreationTime()
+		{
+			return( creation_time );
+		}
+		
+		protected void
+		updateContactDetails(
+			DHTTransportContact		c )
+		{
+			if ( c.getInstanceID() != contact.getInstanceID()){
+				
+				log( "instance id changed" );
+				
+				mappings.clear();
+			}
+			
+			contact	= c;
+		}
+		
+		protected void
+		updateUseTime()
+		{
+			last_used = SystemTime.getMonotonousTime();
+		}
+		
+		protected long
+		getLastUseTime()
+		{
+			return( last_used );
+		}
+		
+		protected void
+		contactOK()
+		{
+			log( "contact ok" );
+			
+			consec_fails	= 0;
+		}
+		
+		protected void
+		contactFailed()
+		{
+			consec_fails++;
+			
+			log( "failed, consec=" + consec_fails );
+			
+			if ( consec_fails >= 2 ){
+				
+				mappings.clear();
+			}
+		}
+		
+		protected int
+		getConsecFails()
+		{
+			return( consec_fails );
+		}
+		
+		protected boolean
+		testMapping(
+			DHTDBMapping	mapping )
+		{
+			return( mappings.contains( mapping ));
+		}
+		
+		protected Set<DHTDBMapping>
+		getMappings()
+		{
+			return( mappings );
+		}
+		
+		protected void
+		addMapping(
+			DHTDBMapping	mapping )
+		{			
+			if ( mappings.add( mapping )){
+				
+				log( "add mapping" );
+			}
+		}
+		
+		protected void
+		removeMapping(
+			DHTDBMapping	mapping )
+		{			
+			if ( mappings.remove( mapping )){
+				
+				log( "remove mapping" );
+			}
+		}
+		
+		protected void
+		log(
+			String	str )
+		{
+			if ( DEBUG_SURVEY ){
+				System.out.println( "s_state: " + contact.getString() + ": " + str );
+			}
+		}
+	}
 }
diff --git a/com/aelitis/azureus/core/dht/db/impl/DHTDBMapping.java b/com/aelitis/azureus/core/dht/db/impl/DHTDBMapping.java
index 010eba2..ed45a93 100644
--- a/com/aelitis/azureus/core/dht/db/impl/DHTDBMapping.java
+++ b/com/aelitis/azureus/core/dht/db/impl/DHTDBMapping.java
@@ -50,12 +50,13 @@ DHTDBMapping
 	
 	private DHTDBImpl			db;
 	private HashWrapper			key;
+	private ShortHash			short_key;
 	private DHTStorageKey		adapter_key;
 	
 		// maps are access order, most recently used at tail, so we cycle values
 		
-	private Map				direct_originator_map_may_be_null;
-	private Map				indirect_originator_value_map		= createLinkedMap();
+	private Map<HashWrapper,DHTDBValueImpl>		direct_originator_map_may_be_null;
+	private Map<HashWrapper,DHTDBValueImpl>		indirect_originator_value_map		= createLinkedMap();
 	
 	private int				hits;
 	
@@ -80,6 +81,8 @@ DHTDBMapping
 		db			= _db;
 		key			= _key;
 		
+		short_key = new ShortHash( key.getBytes());
+		
 		try{
 			if ( db.getAdapter() != null ){
 				
@@ -96,10 +99,10 @@ DHTDBMapping
 		}
 	}
 	
-	protected Map
+	protected  Map<HashWrapper,DHTDBValueImpl>
 	createLinkedMap()
 	{		
-		return( new LinkedHashMap(1, 0.75f, true ));
+		return( new LinkedHashMap<HashWrapper,DHTDBValueImpl>(1, 0.75f, true ));
 	}
 	
 	protected HashWrapper
@@ -108,6 +111,12 @@ DHTDBMapping
 		return( key );
 	}
 
+	protected ShortHash
+	getShortKey()
+	{
+		return( short_key );
+	}
+	
 	protected void
 	updateLocalContact(
 		DHTTransportContact		contact )
@@ -120,13 +129,13 @@ DHTDBMapping
 			return;
 		}
 		
-		List	changed = new ArrayList();
+		List<DHTDBValueImpl>	changed = new ArrayList<DHTDBValueImpl>();
 		
-		Iterator	it = direct_originator_map_may_be_null.values().iterator();
+		Iterator<DHTDBValueImpl>	it = direct_originator_map_may_be_null.values().iterator();
 		
 		while( it.hasNext()){
 		
-			DHTDBValueImpl	value = (DHTDBValueImpl)it.next();
+			DHTDBValueImpl	value = it.next();
 			
 			if ( value.isLocal()){
 			
@@ -146,7 +155,7 @@ DHTDBMapping
 		
 		for (int i=0;i<changed.size();i++){
 			
-			add((DHTDBValueImpl)changed.get(i));
+			add(changed.get(i));
 		}
 	}
 	
@@ -217,17 +226,17 @@ DHTDBMapping
 			
 				// remove any indirect values we might already have for this
 			
-			Iterator	it = indirect_originator_value_map.entrySet().iterator();
+			Iterator<Map.Entry<HashWrapper,DHTDBValueImpl>>	it = indirect_originator_value_map.entrySet().iterator();
 			
-			List	to_remove = new ArrayList();
+			List<HashWrapper>	to_remove = new ArrayList<HashWrapper>();
 			
 			while( it.hasNext()){
 				
-				Map.Entry	entry = (Map.Entry)it.next();
+				Map.Entry<HashWrapper,DHTDBValueImpl>	entry = it.next();
 				
-				HashWrapper		existing_key		= (HashWrapper)entry.getKey();
+				HashWrapper		existing_key	= entry.getKey();
 				
-				DHTDBValueImpl	existing_value	= (DHTDBValueImpl)entry.getValue();
+				DHTDBValueImpl	existing_value	= entry.getValue();
 	
 				if ( Arrays.equals( existing_value.getOriginator().getID(), originator.getID())){
 				
@@ -254,7 +263,7 @@ DHTDBMapping
 				
 			HashWrapper	originator_value_id = getOriginatorValueID( new_value );
 
-			DHTDBValueImpl existing_value = (DHTDBValueImpl)indirect_originator_value_map.get( originator_value_id );
+			DHTDBValueImpl existing_value = indirect_originator_value_map.get( originator_value_id );
 			
 			if ( existing_value != null ){
 				
@@ -365,7 +374,8 @@ DHTDBMapping
 								db.getLocalContact(),
 								true,
 								DHT.FLAG_STATS,
-								0 )});
+								0,
+								DHT.REP_FACT_DEFAULT )});
 					
 				}catch( Throwable e ){
 					
@@ -376,32 +386,32 @@ DHTDBMapping
 			return( new DHTDBValueImpl[0] );
 		}
 		
-		List	res 		= new ArrayList();
+		List<DHTDBValueImpl>	res 		= new ArrayList<DHTDBValueImpl>();
 		
-		Set		duplicate_check = new HashSet();
+		Set<HashWrapper>		duplicate_check = new HashSet<HashWrapper>();
 		
-		Map[]	maps = new Map[]{ direct_originator_map_may_be_null, indirect_originator_value_map };
+		Map<HashWrapper,DHTDBValueImpl>[]	maps = new Map[]{ direct_originator_map_may_be_null, indirect_originator_value_map };
 		
 		for (int i=0;i<maps.length;i++){
 			
-			Map			map	= maps[i];
+			Map<HashWrapper,DHTDBValueImpl>			map	= maps[i];
 			
 			if ( map == null ){
 				
 				continue;
 			}
 			
-			List	keys_used 	= new ArrayList();
+			List<HashWrapper>	keys_used 	= new ArrayList<HashWrapper>();
 
-			Iterator	it = map.entrySet().iterator();
+			Iterator<Map.Entry<HashWrapper,DHTDBValueImpl>>	it = map.entrySet().iterator();
 		
 			while( it.hasNext() && ( max==0 || res.size()< max )){
 			
-				Map.Entry	entry = (Map.Entry)it.next();
+				Map.Entry<HashWrapper,DHTDBValueImpl>	entry = it.next();
 				
-				HashWrapper		entry_key		= (HashWrapper)entry.getKey();
+				HashWrapper		entry_key	= entry.getKey();
 				
-				DHTDBValueImpl	entry_value = (DHTDBValueImpl)entry.getValue();
+				DHTDBValueImpl	entry_value = entry.getValue();
 						
 				HashWrapper	x = new HashWrapper( entry_value.getValue());
 				
@@ -482,19 +492,36 @@ DHTDBMapping
 		return( direct_originator_map_may_be_null.size() + indirect_originator_value_map.size());
 	}
 	
-	protected Iterator
+	protected int
+	getDirectValueCount()
+	{
+		if ( direct_originator_map_may_be_null == null ){
+			
+			return( 0 );
+		}
+		
+		return( direct_originator_map_may_be_null.size());
+	}
+	
+	protected int
+	getIndirectValueCount()
+	{
+		return( indirect_originator_value_map.size());
+	}
+	
+	protected Iterator<DHTDBValueImpl>
 	getValues()
 	{
 		return( new valueIterator( true, true ));
 	}
 	
-	protected Iterator
+	protected Iterator<DHTDBValueImpl>
 	getDirectValues()
 	{
 		return( new valueIterator( true, false ));
 	}
 	
-	protected Iterator
+	protected Iterator<DHTDBValueImpl>
 	getIndirectValues()
 	{
 		return( new valueIterator( false, true ));
@@ -730,7 +757,7 @@ DHTDBMapping
 		try{
 			if ( adapter_key != null ){
 				
-				Iterator	it = getValues();
+				Iterator<DHTDBValueImpl>	it = getValues();
 				
 				while( it.hasNext()){
 					
@@ -970,13 +997,13 @@ DHTDBMapping
 				// only do flood prevention on direct stores as we can't trust the originator
 				// details for indirect and this can be used to DOS a direct store later
 			
-			Iterator	it = getDirectValues();
+			Iterator<DHTDBValueImpl>	it = getDirectValues();
 			
 			int	max_hits	= 0;
 			
 			while( it.hasNext()){
 				
-				DHTDBValueImpl	val = (DHTDBValueImpl)it.next();
+				DHTDBValueImpl	val = it.next();
 				
 				if ( !val.isLocal()){
 					
@@ -1025,18 +1052,30 @@ DHTDBMapping
 			"dir=" + (direct_originator_map_may_be_null==null?0:direct_originator_map_may_be_null.size()) + "," +
 			"indir=" + indirect_originator_value_map.size() + "," +
 			"bloom=" + entries );	
+		
+		System.out.println( "    indirect" );
+		
+		Iterator<DHTDBValueImpl> it = getIndirectValues();
+				
+		while( it.hasNext()){
+			
+			DHTDBValueImpl val = (DHTDBValueImpl)it.next();
+			
+			System.out.println( "        " + val.getOriginator().getString() + ": " + new String( val.getValue()));
+		}
 	}
 	
 	protected class
 	valueIterator
-		implements Iterator
+		implements Iterator<DHTDBValueImpl>
 	{
-		private List	maps 		=	new ArrayList(2); 
+		private List<Map<HashWrapper,DHTDBValueImpl>>	maps 		=	new ArrayList<Map<HashWrapper,DHTDBValueImpl>>(2);
+		
 		private int		map_index 	= 0;
 		
-		private Map				map;
-		private Iterator		it;
-		private DHTDBValueImpl	value;
+		private Map<HashWrapper,DHTDBValueImpl>		map;
+		private Iterator<DHTDBValueImpl>			it;
+		private DHTDBValueImpl						value;
 		
 		protected
 		valueIterator(
@@ -1062,7 +1101,7 @@ DHTDBMapping
 			
 			while( map_index < maps.size() ){
 				
-				map = (Map)maps.get(map_index++);
+				map = maps.get(map_index++);
 				
 				it = map.values().iterator();
 				
@@ -1075,7 +1114,7 @@ DHTDBMapping
 			return( false );
 		}
 		
-		public Object
+		public DHTDBValueImpl
 		next()
 		{
 			if ( hasNext()){
@@ -1126,4 +1165,57 @@ DHTDBMapping
 			}
 		}
 	}
+	
+	public static class 
+	ShortHash 
+	{
+		private byte[]	bytes;
+		private int		hash_code;
+		
+		protected
+		ShortHash(
+			byte[]		_bytes )
+		{
+			bytes	= _bytes;
+			
+			int	hc = 0;
+						
+			for (int i=0; i<DHTDBImpl.QUERY_STORE_REQUEST_ENTRY_SIZE; i++) {
+
+				hc = 31*hc + bytes[i];
+			}
+			
+			hash_code = hc;
+		}
+		
+		public final boolean 
+		equals(
+			Object o) 
+		{
+			if( !( o instanceof ShortHash )){
+				
+				return false;
+			}
+			
+			ShortHash other = (ShortHash)o;
+						
+			byte[]	other_hash 		= other.bytes;
+			
+			for ( int i=0;i<DHTDBImpl.QUERY_STORE_REQUEST_ENTRY_SIZE;i++){
+				
+				if ( bytes[i] != other_hash[i] ){
+					
+					return( false );
+				}
+			}
+			
+			return( true );
+		}
+
+		public int	 
+		hashCode() 
+		{
+			return( hash_code );
+		}
+	}
 }
diff --git a/com/aelitis/azureus/core/dht/db/impl/DHTDBValueImpl.java b/com/aelitis/azureus/core/dht/db/impl/DHTDBValueImpl.java
index 0e36f9f..c6a5a2e 100644
--- a/com/aelitis/azureus/core/dht/db/impl/DHTDBValueImpl.java
+++ b/com/aelitis/azureus/core/dht/db/impl/DHTDBValueImpl.java
@@ -24,6 +24,7 @@ package com.aelitis.azureus.core.dht.db.impl;
 
 import org.gudy.azureus2.core3.util.SystemTime;
 
+import com.aelitis.azureus.core.dht.DHT;
 import com.aelitis.azureus.core.dht.db.DHTDBValue;
 import com.aelitis.azureus.core.dht.impl.DHTLog;
 import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
@@ -47,6 +48,7 @@ DHTDBValueImpl
 	private boolean				local;
 	private byte				flags;
 	private byte				life_hours;
+	private byte				rep_control;
 	private int					version;
 	
 	private long				store_time;
@@ -70,7 +72,8 @@ DHTDBValueImpl
 		DHTTransportContact	_sender,
 		boolean				_local,
 		int					_flags,
-		int					_life_hours )
+		int					_life_hours,
+		byte				_rep_control )
 	{
 		creation_time	= _creation_time;
 		value			= _value;
@@ -80,6 +83,7 @@ DHTDBValueImpl
 		local			= _local;
 		flags			= (byte)_flags;
 		life_hours		= (byte)_life_hours;
+		rep_control		= _rep_control;
 		
 			// we get quite a few zero length values - optimise mem usage
 		
@@ -112,7 +116,8 @@ DHTDBValueImpl
 				_sender,
 				_local,
 				_other.getFlags(),
-				_other.getLifeTimeHours());
+				_other.getLifeTimeHours(),
+				_other.getReplicationControl());
 	}
 	
 	protected void
@@ -202,6 +207,24 @@ DHTDBValueImpl
 		return( life_hours&0xff );
 	}
 	
+	public byte
+	getReplicationControl()
+	{
+		return( rep_control );
+	}
+	
+	public byte 
+	getReplicationFactor() 
+	{
+		return( rep_control == DHT.REP_FACT_DEFAULT?DHT.REP_FACT_DEFAULT:(byte)(rep_control&0x0f));
+	}
+	
+	public byte 
+	getReplicationFrequencyHours() 
+	{
+		return( rep_control == DHT.REP_FACT_DEFAULT?DHT.REP_FACT_DEFAULT:(byte)((rep_control&0xf0)>>4));
+	}
+	
 	protected void
 	setOriginatorAndSender(
 		DHTTransportContact	_originator )
@@ -238,7 +261,7 @@ DHTDBValueImpl
 		long	now = SystemTime.getCurrentTime();
 		
 		return( DHTLog.getString( value ) + " - " + new String(value) + "{v=" + version + ",f=" + 
-				Integer.toHexString(flags) +",ca=" + (now - creation_time ) + ",sa=" + (now-store_time)+
+				Integer.toHexString(flags) + ",l=" + life_hours + ",r=" + Integer.toHexString( rep_control ) + ",ca=" + (now - creation_time ) + ",sa=" + (now-store_time)+
 				",se=" + sender.getString() + ",or=" + originator.getString() +"}" );
 	}
 }
diff --git a/com/aelitis/azureus/core/dht/impl/DHTImpl.java b/com/aelitis/azureus/core/dht/impl/DHTImpl.java
index c82f21c..36d46ce 100644
--- a/com/aelitis/azureus/core/dht/impl/DHTImpl.java
+++ b/com/aelitis/azureus/core/dht/impl/DHTImpl.java
@@ -108,6 +108,7 @@ DHTImpl
 					
 					public byte[][]
 					diversify(
+						String				description,
 						DHTTransportContact	cause,
 						boolean				put_operation,
 						boolean				existing,
@@ -137,7 +138,7 @@ DHTImpl
 								
 							}else{
 								
-								return( storage_adapter.createNewDiversification( cause, key, put_operation, type, exhaustive, max_depth ));
+								return( storage_adapter.createNewDiversification( description, cause, key, put_operation, type, exhaustive, max_depth ));
 							}
 						}else{
 							
@@ -210,7 +211,7 @@ DHTImpl
 		byte					flags,
 		DHTOperationListener	listener )
 	{
-		control.put( key, description, value, flags, (byte)0, true, listener );
+		control.put( key, description, value, flags, (byte)0, DHT.REP_FACT_DEFAULT, true, listener );
 	}
 	
 	public void
@@ -222,7 +223,7 @@ DHTImpl
 		boolean					high_priority,
 		DHTOperationListener	listener )
 	{
-		control.put( key, description, value, flags, (byte)0, high_priority, listener );
+		control.put( key, description, value, flags, (byte)0, DHT.REP_FACT_DEFAULT, high_priority, listener );
 	}
 	
 	public void
@@ -235,7 +236,21 @@ DHTImpl
 		boolean					high_priority,
 		DHTOperationListener	listener )
 	{
-		control.put( key, description, value, flags, life_hours, high_priority, listener );
+		control.put( key, description, value, flags, life_hours, DHT.REP_FACT_DEFAULT, high_priority, listener );
+	}
+	
+	public void
+	put(
+		byte[]					key,
+		String					description,
+		byte[]					value,
+		byte					flags,
+		byte					life_hours,
+		byte					replication_control,
+		boolean					high_priority,
+		DHTOperationListener	listener )
+	{
+		control.put( key, description, value, flags, life_hours, replication_control, high_priority, listener );
 	}
 	
 	public DHTTransportValue
diff --git a/com/aelitis/azureus/core/dht/impl/DHTLog.java b/com/aelitis/azureus/core/dht/impl/DHTLog.java
index 193ccf0..e728dcd 100644
--- a/com/aelitis/azureus/core/dht/impl/DHTLog.java
+++ b/com/aelitis/azureus/core/dht/impl/DHTLog.java
@@ -274,7 +274,7 @@ DHTLog
 				return( "<null>");
 			}
 			
-			return( getString( value.getValue()) + "<" + (value.isLocal()?"local":"remote" ) + ",flags=" + value.getFlags() + ",life=" + value.getLifeTimeHours() + ",orig=" + value.getOriginator().getExternalAddress() +">" );
+			return( getString( value.getValue()) + " <" + (value.isLocal()?"loc":"rem" ) + ",flag=" + Integer.toHexString(value.getFlags()) + ",life=" + value.getLifeTimeHours() + ",rep=" + Integer.toHexString( value.getReplicationControl())+",orig=" + value.getOriginator().getExternalAddress() +">" );
 		}else{
 			return( "" );
 		}
diff --git a/com/aelitis/azureus/core/dht/impl/Test.java b/com/aelitis/azureus/core/dht/impl/Test.java
index fbc9845..dbe3a10 100644
--- a/com/aelitis/azureus/core/dht/impl/Test.java
+++ b/com/aelitis/azureus/core/dht/impl/Test.java
@@ -72,8 +72,8 @@ Test
 		DHTTransportUDPImpl.TEST_EXTERNAL_IP	= true;
 	}
 	
-	int num_dhts			= 3;
-	int num_stores			= 2;
+	int num_dhts			= 6;
+	int num_stores			= 0;
 	static int MAX_VALUES	= 10000;
 	
 	boolean	udp_protocol	= true;
@@ -89,7 +89,7 @@ Test
 	static Properties	dht_props = new Properties();
 	
 	static{		
-		DHTDBImpl.ORIGINAL_REPUBLISH_INTERVAL_GRACE = 0;
+		// DHTDBImpl.ORIGINAL_REPUBLISH_INTERVAL_GRACE = 0;
 
 		dht_props.put( DHT.PR_CONTACTS_PER_NODE, new Integer(K));
 		dht_props.put( DHT.PR_NODE_SPLIT_FACTOR, new Integer(B));
@@ -355,8 +355,9 @@ Test
 							
 							pos = val.indexOf( ' ' );
 							
-							byte flags 	= 0;
-							byte life 	= 0;
+							byte flags 		= 0;
+							byte life 		= 0;
+							byte rep_fact 	= DHT.REP_FACT_DEFAULT;
 							
 							if ( pos != -1 ){
 								
@@ -372,18 +373,23 @@ Test
 									
 									if ( opt.equals( "f" )){
 										
-										flags = (byte)Integer.parseInt(y[1]);
+										flags = (byte)Integer.parseInt(y[1],16);
 										
 									}else if ( opt.equals( "l" )){
 										
 										life = (byte)Integer.parseInt(y[1]);
+										
+									}else if ( opt.equals( "r" )){
+										
+										rep_fact = (byte)Integer.parseInt(y[1]);
+
 									}
 								}
 								
 								val = val.substring(0,pos);
 							}
 							
-							dht.put( key.getBytes(), "", val.getBytes(), flags, life, false, new DHTOperationAdapter() );
+							dht.put( key.getBytes(), "", val.getBytes(), flags, life, rep_fact, false, new DHTOperationAdapter() );
 						}
 					}else if ( command == 'x' ){
 						
@@ -428,8 +434,33 @@ Test
 						
 						stats_before = dht.getTransport().getStats().snapshot();
 					
+						pos = rhs.indexOf( ' ' );
+						
+						byte flags 	= 0;
+						
+						if ( pos != -1 ){
+							
+							String	opts = rhs.substring( pos+1 );
+							
+							String[] x = opts.split( "," );
+							
+							for ( String s: x ){
+								
+								String[] y = s.split("=");
+								
+								String	opt = y[0];
+								
+								if ( opt.equals( "f" )){
+									
+									flags = (byte)Integer.parseInt(y[1]);
+								}
+							}
+							
+							rhs = rhs.substring(0,pos);
+						}
+						
 						dht.get( 
-								rhs.getBytes(), "", (byte)0, 32, 0, false, false,
+								rhs.getBytes(), "", flags, 32, 0, false, false,
 								new DHTOperationAdapter()
 								{
 									public void
@@ -523,7 +554,8 @@ Test
 									
 									public void
 									found(
-										DHTTransportContact	contact )
+										DHTTransportContact	contact,
+										boolean				is_closest )
 									{
 									}
 									
@@ -910,8 +942,9 @@ Test
 		DHTTransportValue		value )
 	{
 		return( new String( value.getValue()) + 
-				"; flags=" + value.getFlags() +
+				"; flags=" + Integer.toHexString( value.getFlags()) +
 				"; life=" + value.getLifeTimeHours() +
+				"; rep=" + Integer.toHexString( value.getReplicationControl())  +
 				", orig=" + value.getOriginator().getAddress());
 	}
 	
diff --git a/com/aelitis/azureus/core/dht/nat/impl/DHTNATPuncherImpl.java b/com/aelitis/azureus/core/dht/nat/impl/DHTNATPuncherImpl.java
index e7de391..af4692f 100644
--- a/com/aelitis/azureus/core/dht/nat/impl/DHTNATPuncherImpl.java
+++ b/com/aelitis/azureus/core/dht/nat/impl/DHTNATPuncherImpl.java
@@ -648,7 +648,8 @@ DHTNATPuncherImpl
       										
       										public void
       										found(
-      											DHTTransportContact	contact )
+      											DHTTransportContact	contact,
+      											boolean				is_closest )
       										{}
       										
       										public void
@@ -698,7 +699,8 @@ DHTNATPuncherImpl
       										
       										public void
       										found(
-      											DHTTransportContact	contact )
+      											DHTTransportContact	contact,
+      											boolean				is_closest )
       										{}
       										
       										public void
@@ -751,7 +753,8 @@ DHTNATPuncherImpl
       									
       									public void
       									found(
-      										DHTTransportContact	contact )
+      										DHTTransportContact	contact,
+      										boolean				is_closest )
       									{}
       									
       									public void
diff --git a/com/aelitis/azureus/core/dht/router/DHTRouter.java b/com/aelitis/azureus/core/dht/router/DHTRouter.java
index 7eb76f2..46ae892 100644
--- a/com/aelitis/azureus/core/dht/router/DHTRouter.java
+++ b/com/aelitis/azureus/core/dht/router/DHTRouter.java
@@ -103,7 +103,7 @@ DHTRouter
 		 * Returns num_to_return or a few more closest contacts, unordered
 		 */
 	
-	public List
+	public List<DHTRouterContact>
 	findClosestContacts(
 		byte[]		node_id,
 		int			num_to_return,
@@ -130,7 +130,7 @@ DHTRouter
 		 * @return
 		 */
 	
-	public List
+	public List<DHTRouterContact>
 	findBestContacts(
 		int		max );
 	
diff --git a/com/aelitis/azureus/core/dht/router/impl/DHTRouterImpl.java b/com/aelitis/azureus/core/dht/router/impl/DHTRouterImpl.java
index 584942f..1bc6888 100644
--- a/com/aelitis/azureus/core/dht/router/impl/DHTRouterImpl.java
+++ b/com/aelitis/azureus/core/dht/router/impl/DHTRouterImpl.java
@@ -102,6 +102,13 @@ DHTRouterImpl
 	
 	private TimerEventPeriodic	timer_event;
 	
+	private volatile int seed_in_ticks;
+	
+	private static final int	TICK_PERIOD 		= 10*1000;
+	private static final int	SEED_DELAY_PERIOD	= 60*1000;
+	private static final int	SEED_DELAY_TICKS	= SEED_DELAY_PERIOD/TICK_PERIOD;
+	
+	
 	public
 	DHTRouterImpl(
 		int										_K,
@@ -150,7 +157,7 @@ DHTRouterImpl
 		
 		timer_event = SimpleTimer.addPeriodicEvent(
 			"DHTRouter:pinger",
-			10*1000,
+			TICK_PERIOD,
 			new TimerEventPerformer()
 			{
 				public void 
@@ -158,6 +165,16 @@ DHTRouterImpl
 					TimerEvent event ) 
 				{
 					pingeroonies();
+					
+					if ( seed_in_ticks > 0 ){
+						
+						seed_in_ticks--;
+						
+						if ( seed_in_ticks == 0 ){
+							
+							seedSupport();
+						}
+					}
 				}
 			});
 	}
@@ -894,6 +911,15 @@ DHTRouterImpl
 	public void
 	seed()
 	{
+			// defer this a while to see how much refreshing is done by the normal DHT traffic
+		
+		seed_in_ticks = SEED_DELAY_TICKS;
+	}
+	
+	protected void
+	seedSupport()
+	{
+			
 			// refresh all buckets apart from closest neighbour
 		
 		byte[]	path = new byte[router_node_id.length];
@@ -903,7 +929,7 @@ DHTRouterImpl
 		try{
 			this_mon.enter();
 			
-			refreshNodes( ids, root, path, true, 0 );
+			refreshNodes( ids, root, path, true, SEED_DELAY_PERIOD * 2 );
 			
 		}finally{
 			
diff --git a/com/aelitis/azureus/core/dht/transport/DHTTransport.java b/com/aelitis/azureus/core/dht/transport/DHTTransport.java
index 6036cbd..c504141 100644
--- a/com/aelitis/azureus/core/dht/transport/DHTTransport.java
+++ b/com/aelitis/azureus/core/dht/transport/DHTTransport.java
@@ -127,6 +127,9 @@ DHTTransport
 	public DHTTransportContact[]
 	getReachableContacts();
 	
+	public DHTTransportContact[]
+	getRecentContacts();
+	
 	public void
 	addListener(
 		DHTTransportListener	l );
diff --git a/com/aelitis/azureus/core/dht/transport/DHTTransportContact.java b/com/aelitis/azureus/core/dht/transport/DHTTransportContact.java
index f4db00d..13c26e4 100644
--- a/com/aelitis/azureus/core/dht/transport/DHTTransportContact.java
+++ b/com/aelitis/azureus/core/dht/transport/DHTTransportContact.java
@@ -27,6 +27,7 @@ package com.aelitis.azureus.core.dht.transport;
  *
  */
 
+import java.util.*;
 import java.io.*;
 import java.net.InetSocketAddress;
 
@@ -73,6 +74,11 @@ DHTTransportContact
 	isAlive(
 		long		timeout );
 
+	public void
+	isAlive(
+		DHTTransportReplyHandler	handler,
+		long						timeout );
+	
 	public boolean
 	isValid();
 	
@@ -97,6 +103,12 @@ DHTTransportContact
 		boolean						immediate );
 	
 	public void
+	sendQueryStore(
+		DHTTransportReplyHandler	handler,
+		int							header_length,
+		List<Object[]>				key_details );
+	
+	public void
 	sendFindNode(
 		DHTTransportReplyHandler	handler,
 		byte[]						id );
diff --git a/com/aelitis/azureus/core/dht/transport/DHTTransportQueryStoreReply.java b/com/aelitis/azureus/core/dht/transport/DHTTransportQueryStoreReply.java
new file mode 100644
index 0000000..ba3d43d
--- /dev/null
+++ b/com/aelitis/azureus/core/dht/transport/DHTTransportQueryStoreReply.java
@@ -0,0 +1,34 @@
+/*
+ * Created on Sep 29, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.dht.transport;
+
+import java.util.List;
+
+public interface 
+DHTTransportQueryStoreReply 
+{
+	public int
+	getHeaderSize();
+	
+	public List<byte[]>
+	getEntries();
+}
diff --git a/com/aelitis/azureus/core/dht/transport/DHTTransportReplyHandler.java b/com/aelitis/azureus/core/dht/transport/DHTTransportReplyHandler.java
index 94e7395..f067f7a 100644
--- a/com/aelitis/azureus/core/dht/transport/DHTTransportReplyHandler.java
+++ b/com/aelitis/azureus/core/dht/transport/DHTTransportReplyHandler.java
@@ -27,6 +27,8 @@ package com.aelitis.azureus.core.dht.transport;
  *
  */
 
+import java.util.*;
+
 public interface 
 DHTTransportReplyHandler 
 {
@@ -46,6 +48,11 @@ DHTTransportReplyHandler
 		byte[]				diversifications );
 	
 	public void
+	queryStoreReply(
+		DHTTransportContact contact,
+		List<byte[]>		response );
+	
+	public void
 	findNodeReply(
 		DHTTransportContact 	contact,
 		DHTTransportContact[]	contacts );
diff --git a/com/aelitis/azureus/core/dht/transport/DHTTransportReplyHandlerAdapter.java b/com/aelitis/azureus/core/dht/transport/DHTTransportReplyHandlerAdapter.java
index c88e7d0..7c1d8bd 100644
--- a/com/aelitis/azureus/core/dht/transport/DHTTransportReplyHandlerAdapter.java
+++ b/com/aelitis/azureus/core/dht/transport/DHTTransportReplyHandlerAdapter.java
@@ -22,6 +22,8 @@
 
 package com.aelitis.azureus.core.dht.transport;
 
+import java.util.List;
+
 import org.gudy.azureus2.core3.util.Debug;
 
 /**
@@ -75,6 +77,14 @@ DHTTransportReplyHandlerAdapter
 	}
 	
 	public void
+	queryStoreReply(
+		DHTTransportContact contact,
+		List<byte[]>		response )
+	{
+		throw( new RuntimeException( "Not implemented" ));
+	}
+	
+	public void
 	findNodeReply(
 		DHTTransportContact 	contact,
 		DHTTransportContact[]	contacts )
diff --git a/com/aelitis/azureus/core/dht/transport/DHTTransportRequestHandler.java b/com/aelitis/azureus/core/dht/transport/DHTTransportRequestHandler.java
index 0dc2a64..23d94ce 100644
--- a/com/aelitis/azureus/core/dht/transport/DHTTransportRequestHandler.java
+++ b/com/aelitis/azureus/core/dht/transport/DHTTransportRequestHandler.java
@@ -27,6 +27,8 @@ package com.aelitis.azureus.core.dht.transport;
  *
  */
 
+import java.util.*;
+
 public interface 
 DHTTransportRequestHandler 
 {
@@ -50,6 +52,12 @@ DHTTransportRequestHandler
 		byte[][]				keys,
 		DHTTransportValue[][]	value_sets );
 	
+	public DHTTransportQueryStoreReply
+	queryStoreRequest(
+		DHTTransportContact 	contact, 
+		int						header_len,
+		List<Object[]>			keys );
+	
 	public DHTTransportContact[]
 	findNodeRequest(
 		DHTTransportContact contact, 
diff --git a/com/aelitis/azureus/core/dht/transport/DHTTransportStats.java b/com/aelitis/azureus/core/dht/transport/DHTTransportStats.java
index 42ee399..f51cd7e 100644
--- a/com/aelitis/azureus/core/dht/transport/DHTTransportStats.java
+++ b/com/aelitis/azureus/core/dht/transport/DHTTransportStats.java
@@ -54,6 +54,9 @@ DHTTransportStats
 	getStores();
 	
 	public long[]
+	getQueryStores();
+	
+	public long[]
 	getData();
 	
 	public long[]
@@ -67,6 +70,7 @@ DHTTransportStats
 	public static final int AT_STATS			= 3; 
 	public static final int AT_STORE			= 4; 
 	public static final int AT_KEY_BLOCK		= 5; 
+	public static final int AT_QUERY_STORE		= 6; 
 	
 	public long[]
 	getAliens();
diff --git a/com/aelitis/azureus/core/dht/transport/DHTTransportValue.java b/com/aelitis/azureus/core/dht/transport/DHTTransportValue.java
index f1438c3..5ee7df7 100644
--- a/com/aelitis/azureus/core/dht/transport/DHTTransportValue.java
+++ b/com/aelitis/azureus/core/dht/transport/DHTTransportValue.java
@@ -51,6 +51,15 @@ DHTTransportValue
 	public int
 	getLifeTimeHours();
 	
+	public byte
+	getReplicationControl();
+	
+	public byte
+	getReplicationFactor();
+
+	public byte
+	getReplicationFrequencyHours();
+
 	public String
 	getString();
 }
diff --git a/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackContactImpl.java b/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackContactImpl.java
index 6503b82..ecf6b53 100644
--- a/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackContactImpl.java
+++ b/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackContactImpl.java
@@ -24,6 +24,8 @@ package com.aelitis.azureus.core.dht.transport.loopback;
 
 import java.io.*;
 import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.Map;
 
 import com.aelitis.azureus.core.dht.impl.DHTLog;
 import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPosition;
@@ -131,6 +133,14 @@ DHTTransportLoopbackContactImpl
 		return( true );
 	}
 
+	public void 
+	isAlive(
+		DHTTransportReplyHandler 	handler, 
+		long 						timeout )
+	{
+		transport.sendPing( this, handler );
+	}
+	
 	public void
 	sendPing(
 		DHTTransportReplyHandler	handler )
@@ -172,6 +182,15 @@ DHTTransportLoopbackContactImpl
 		transport.sendStore( this, handler, keys, value_sets, false );
 	}
 	
+	public void 
+	sendQueryStore(
+		DHTTransportReplyHandler 	handler,
+		int							header_length,
+		List<Object[]>			 	key_details ) 
+	{
+		transport.sendQueryStore( this, handler, header_length, key_details);
+	}
+	
 	public void
 	sendFindNode(
 		DHTTransportReplyHandler	handler,
diff --git a/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackImpl.java b/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackImpl.java
index c06f26d..542242b 100644
--- a/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackImpl.java
+++ b/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackImpl.java
@@ -222,6 +222,12 @@ DHTTransportLoopbackImpl
 		return( new DHTTransportContact[0] );
 	}
 	
+	public DHTTransportContact[]
+	getRecentContacts()
+	{
+		return( new DHTTransportContact[0] );
+	}
+	
 	protected DHTTransportLoopbackImpl
 	findTarget(
 		byte[]		id )
@@ -530,6 +536,18 @@ DHTTransportLoopbackImpl
 		}
 	}
 	
+		// QUERY STORE
+	
+	public void 
+	sendQueryStore(
+		DHTTransportContact			contact,
+		DHTTransportReplyHandler 	handler,
+		int							header_length,
+		List<Object[]>				key_details ) 
+	{
+		handler.failed( contact, new Throwable( "not implemented" ));
+	}
+	
 		// FIND NODE
 	
 	public void
diff --git a/com/aelitis/azureus/core/dht/transport/udp/DHTTransportUDP.java b/com/aelitis/azureus/core/dht/transport/udp/DHTTransportUDP.java
index a98e8ac..5dc09c6 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/DHTTransportUDP.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/DHTTransportUDP.java
@@ -44,6 +44,7 @@ DHTTransportUDP
 	public static final byte PROTOCOL_VERSION_2502					= 16;	
 	public static final byte PROTOCOL_VERSION_3111					= 17;	
 	public static final byte PROTOCOL_VERSION_4204					= 22;	// min -> 17
+	public static final byte PROTOCOL_VERSION_4208					= 23;	
 
 	public static final byte PROTOCOL_VERSION_DIV_AND_CONT			= 6;
 	public static final byte PROTOCOL_VERSION_ANTI_SPOOF			= 7;
@@ -71,22 +72,30 @@ DHTTransportUDP
 	public static final byte PROTOCOL_VERSION_CVS_FIX_OVERLOAD_V3	= 21;
 	public static final byte PROTOCOL_VERSION_MORE_NODE_STATUS		= 22;
 	public static final byte PROTOCOL_VERSION_LONGER_LIFE			= 23;
+	public static final byte PROTOCOL_VERSION_REPLICATION_CONTROL	= 24;
+	public static final byte PROTOCOL_VERSION_REPLICATION_CONTROL2	= 25;
+	public static final byte PROTOCOL_VERSION_REPLICATION_CONTROL3	= 26;
 
 	
 	public static final byte PROTOCOL_VERSION_RESTRICT_ID_PORTS		= 32;	// introduced now (2403/V15) to support possible future change to id allocation
 																			// If/when introduced the min DHT version must be set to 15 at the same time
 
+	public static final byte PROTOCOL_VERSION_RESTRICT_ID_PORTS2	= 33;
+	public static final byte PROTOCOL_VERSION_RESTRICT_ID_PORTS2X	= 34;	// nothing new here - added to we can track CVS user's access to replication control
+	public static final byte PROTOCOL_VERSION_RESTRICT_ID_PORTS2Y	= 35;	// another one to track fix to broken rep factor handling
+	public static final byte PROTOCOL_VERSION_RESTRICT_ID_PORTS2Z	= 36;	// hopefully last one - needed to excluded nodes that don't support replication frequency
+	
 		// multiple networks reformats the requests and therefore needs the above fix to work
 	
 	public static final byte PROTOCOL_VERSION_NETWORKS				= PROTOCOL_VERSION_FIX_ORIGINATOR;
 	
 		// current versions
 	
-	public static final byte PROTOCOL_VERSION_MAIN					= PROTOCOL_VERSION_LONGER_LIFE;
-	public static final byte PROTOCOL_VERSION_CVS					= PROTOCOL_VERSION_LONGER_LIFE;
+	public static final byte PROTOCOL_VERSION_MAIN					= PROTOCOL_VERSION_REPLICATION_CONTROL3;
+	public static final byte PROTOCOL_VERSION_CVS					= PROTOCOL_VERSION_RESTRICT_ID_PORTS2Z;
 
-	public static final byte PROTOCOL_VERSION_MIN					= PROTOCOL_VERSION_3111;
-	public static final byte PROTOCOL_VERSION_MIN_CVS				= PROTOCOL_VERSION_CVS_FIX_OVERLOAD_V3;
+	public static final byte PROTOCOL_VERSION_MIN					= PROTOCOL_VERSION_MORE_NODE_STATUS;
+	public static final byte PROTOCOL_VERSION_MIN_CVS				= PROTOCOL_VERSION_RESTRICT_ID_PORTS2Z;
 	
 	
 	
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPContactImpl.java b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPContactImpl.java
index eb32866..4e56bc3 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPContactImpl.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPContactImpl.java
@@ -25,6 +25,8 @@ package com.aelitis.azureus.core.dht.transport.udp.impl;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.Map;
 
 import org.gudy.azureus2.core3.util.AESemaphore;
 
@@ -269,6 +271,14 @@ DHTTransportUDPContactImpl
 		}
 	}
 
+	public void 
+	isAlive(
+		DHTTransportReplyHandler 	handler, 
+		long 						timeout )
+	{
+		transport.sendPing( this, handler, timeout, PRUDPPacketHandler.PRIORITY_IMMEDIATE );		
+	}
+	
 	public void
 	sendPing(
 		DHTTransportReplyHandler	handler )
@@ -303,6 +313,15 @@ DHTTransportUDPContactImpl
 				immediate?PRUDPPacketHandler.PRIORITY_IMMEDIATE:PRUDPPacketHandler.PRIORITY_LOW );
 	}
 	
+	public void 
+	sendQueryStore(
+		DHTTransportReplyHandler 	handler,
+		int							header_length,
+		List<Object[]>			 	key_details ) 
+	{
+		transport.sendQueryStore( this, handler, header_length, key_details);
+	}
+	
 	public void
 	sendFindNode(
 		DHTTransportReplyHandler	handler,
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPImpl.java b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPImpl.java
index 5c8fc8b..46c3e61 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPImpl.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPImpl.java
@@ -151,25 +151,25 @@ DHTTransportUDPImpl
 	private static final int CONTACT_HISTORY_MAX 		= 32;
 	private static final int CONTACT_HISTORY_PING_SIZE	= 24;
 	
-	private Map	contact_history = 
-		new LinkedHashMap(CONTACT_HISTORY_MAX,0.75f,true)
+	private Map<InetSocketAddress,DHTTransportContact>	contact_history = 
+		new LinkedHashMap<InetSocketAddress,DHTTransportContact>(CONTACT_HISTORY_MAX,0.75f,true)
 		{
 			protected boolean 
 			removeEldestEntry(
-		   		Map.Entry eldest) 
+		   		Map.Entry<InetSocketAddress,DHTTransportContact> eldest) 
 			{
 				return size() > CONTACT_HISTORY_MAX;
 			}
 		};
 		
-	private static final int ROUTABLE_CONTACT_HISTORY_MAX 		= 32;
+	private static final int ROUTABLE_CONTACT_HISTORY_MAX 		= 64;
 
-	private Map	routable_contact_history = 
-		new LinkedHashMap(ROUTABLE_CONTACT_HISTORY_MAX,0.75f,true)
+	private Map<InetSocketAddress,DHTTransportContact>	routable_contact_history = 
+		new LinkedHashMap<InetSocketAddress,DHTTransportContact>(ROUTABLE_CONTACT_HISTORY_MAX,0.75f,true)
 		{
 			protected boolean 
 			removeEldestEntry(
-		   		Map.Entry eldest) 
+		   		Map.Entry<InetSocketAddress,DHTTransportContact> eldest) 
 			{
 				return size() > ROUTABLE_CONTACT_HISTORY_MAX;
 			}
@@ -947,7 +947,27 @@ DHTTransportUDPImpl
 		try{
 			this_mon.enter();
 			
-			Collection vals = routable_contact_history.values();
+			Collection<DHTTransportContact> vals = routable_contact_history.values();
+			
+			DHTTransportContact[]	res = new DHTTransportContact[vals.size()];
+			
+			vals.toArray( res );
+			
+			return( res );
+			
+		}finally{
+			
+			this_mon.exit();
+		}
+   	}
+	
+	public DHTTransportContact[]
+   	getRecentContacts()
+   	{
+		try{
+			this_mon.enter();
+			
+			Collection<DHTTransportContact> vals = contact_history.values();
 			
 			DHTTransportContact[]	res = new DHTTransportContact[vals.size()];
 			
@@ -988,7 +1008,7 @@ DHTTransportUDPImpl
 							
 							other_routable_total++;
 						}
-						
+												
 						routable_contact_history.put( contact.getTransportAddress(), contact );
 						
 					}else{
@@ -1879,6 +1899,221 @@ DHTTransportUDPImpl
 		}
 	}
 	
+		// QUERY STORE
+	
+	public void 
+	sendQueryStore(
+		final DHTTransportUDPContactImpl	contact,
+		final DHTTransportReplyHandler 		handler,
+		int									header_size,
+		List<Object[]>						key_details )
+	{
+		try{
+			checkAddress( contact );
+			
+			final long	connection_id = getConnectionID();
+			
+			Iterator<Object[]> it = key_details.iterator();
+			
+			byte[]				current_prefix			= null;
+			Iterator<byte[]>	current_suffixes 		= null;
+						
+			List<DHTUDPPacketRequestQueryStorage> requests = new ArrayList<DHTUDPPacketRequestQueryStorage>();
+	
+outer:	
+			while( it.hasNext()){
+
+				int	space = DHTUDPPacketRequestQueryStorage.SPACE;
+
+				DHTUDPPacketRequestQueryStorage	request = 
+					new DHTUDPPacketRequestQueryStorage( this, connection_id, local_contact, contact );
+
+				List<Object[]> packet_key_details = new ArrayList<Object[]>();
+				
+				while( space > 0 && it.hasNext()){
+					
+					if ( current_prefix == null ){
+					
+						Object[] entry = it.next();
+					
+						current_prefix = (byte[])entry[0];
+					
+						List<byte[]> l = (List<byte[]>)entry[1];
+						
+						current_suffixes = l.iterator();
+					}
+					
+					if ( current_suffixes.hasNext()){
+						
+						int	min_space = header_size + 3;	// 1 byte prefix len, 2 byte num suffix
+						
+						if ( space < min_space ){
+							
+							request.setDetails( header_size, packet_key_details );
+							
+							requests.add( request );
+							
+							continue outer ;
+						}
+						
+						List<byte[]> s = new ArrayList<byte[]>();
+						
+						packet_key_details.add( new Object[]{ current_prefix, s });
+						
+						int	prefix_size = current_prefix.length;
+						int	suffix_size = header_size - prefix_size;
+
+						space -= ( 3 + prefix_size );
+						
+						while( space >= suffix_size && current_suffixes.hasNext()){
+							
+							s.add( current_suffixes.next());
+						}
+						
+					}else{
+						
+						current_prefix = null;
+					}
+				}
+				
+				if ( !it.hasNext()){
+					
+					request.setDetails( header_size, packet_key_details );
+					
+					requests.add( request );
+				}
+			}
+
+			final Object[] replies = new Object[ requests.size() ];
+							
+			for ( int i=0;i<requests.size();i++){
+				
+				DHTUDPPacketRequestQueryStorage request = requests.get(i);
+				
+				final int f_i = i;
+					
+				stats.queryStoreSent( request );
+							
+				requestSendRequestProcessor( contact, request );
+	
+				packet_handler.sendAndReceive(
+					request,
+					contact.getTransportAddress(),
+					new DHTUDPPacketReceiver()
+					{					
+						public void
+						packetReceived(
+							DHTUDPPacketReply	packet,
+							InetSocketAddress	from_address,
+							long				elapsed_time )
+						{
+							try{														
+								if ( packet.getConnectionId() != connection_id ){
+									
+									throw( new Exception( "connection id mismatch" ));
+								}
+	
+								contact.setInstanceIDAndVersion( packet.getTargetInstanceID(), packet.getProtocolVersion());
+								
+								requestSendReplyProcessor( contact, handler, packet, elapsed_time );
+									
+								DHTUDPPacketReplyQueryStorage	reply = (DHTUDPPacketReplyQueryStorage)packet;
+								
+									// copy out the random id in preparation for a possible subsequent
+									// store operation
+								
+								contact.setRandomID( reply.getRandomID());
+																							
+								stats.queryStoreOK();
+									
+								synchronized( replies ){
+									
+									replies[f_i] = reply;
+									
+									checkComplete();
+								}
+								
+							}catch( DHTUDPPacketHandlerException e ){
+								
+								error( e );
+								
+							}catch( Throwable e ){
+								
+								Debug.printStackTrace(e);
+								
+								error( new DHTUDPPacketHandlerException( "queryStore failed", e ));
+							}
+						}
+						
+						public void
+						error(
+							DHTUDPPacketHandlerException	e )
+						{
+							stats.queryStoreFailed();
+							
+							synchronized( replies ){
+								
+								replies[f_i] = e;
+								
+								checkComplete();
+							}
+						}
+						
+						protected void
+						checkComplete()
+						{
+							DHTUDPPacketHandlerException last_error = null;
+							
+							for ( int i=0;i<replies.length;i++ ){
+							
+								Object o = replies[i];
+								
+								if ( o == null ){
+									
+									return;
+								}
+								
+								if ( o instanceof DHTUDPPacketHandlerException ){
+									
+									last_error = (DHTUDPPacketHandlerException)o;
+								}
+							}
+							
+							if ( last_error != null ){
+							
+								handler.failed( contact, last_error );
+								
+							}else{
+							
+								if ( replies.length == 1 ){
+									
+									handler.queryStoreReply( contact, ((DHTUDPPacketReplyQueryStorage)replies[0]).getResponse());
+									
+								}else{
+									
+									List<byte[]> response = new ArrayList<byte[]>();
+							
+									for ( int i=0;i<replies.length;i++ ){
+									
+										response.addAll(((DHTUDPPacketReplyQueryStorage)replies[0]).getResponse());
+									}
+								
+									handler.queryStoreReply( contact, response );
+								}
+							}
+						}
+					},
+					request_timeout, PRUDPPacketHandler.PRIORITY_MEDIUM );
+			}
+			
+		}catch( Throwable e ){
+			
+			stats.queryStoreFailed();
+			
+			handler.failed( contact, e );
+		}
+	}
+	
 		// FIND NODE
 	
 	public void
@@ -3361,6 +3596,31 @@ DHTTransportUDPImpl
 							packet_handler.send( reply, request.getAddress());
 						}
 					}
+				}else if ( request instanceof DHTUDPPacketRequestQueryStorage ){
+					
+					DHTUDPPacketRequestQueryStorage	query_request = (DHTUDPPacketRequestQueryStorage)request;
+					
+					DHTTransportQueryStoreReply	res = 
+						request_handler.queryStoreRequest(
+									originating_contact,
+									query_request.getHeaderLength(),
+									query_request.getKeys());		
+					
+					DHTUDPPacketReplyQueryStorage	reply = 
+						new DHTUDPPacketReplyQueryStorage(
+								this,
+								request.getTransactionId(),
+								request.getConnectionId(),
+								local_contact,
+								originating_contact );
+							
+					reply.setRandomID( originating_contact.getRandomID());
+						
+					reply.setResponse( res.getHeaderSize(), res.getEntries());
+					
+					requestReceiveReplyProcessor( originating_contact, reply );
+
+					packet_handler.send( reply, request.getAddress());
 					
 				}else if ( request instanceof DHTUDPPacketRequestFindNode ){
 					
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketData.java b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketData.java
index 73f0125..4384ea7 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketData.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketData.java
@@ -27,6 +27,7 @@ import java.io.DataOutputStream;
 import java.io.IOException;
 
 import com.aelitis.azureus.core.dht.impl.DHTLog;
+import com.aelitis.azureus.core.dht.transport.udp.DHTTransportUDP;
 import com.aelitis.azureus.core.dht.transport.udp.impl.packethandler.DHTUDPPacketNetworkHandler;
 
 
@@ -80,7 +81,19 @@ DHTUDPPacketData
 		
 		packet_type		= is.readByte();
 		transfer_key	= DHTUDPUtils.deserialiseByteArray( is, 64 );
-		key				= DHTUDPUtils.deserialiseByteArray( is, 64 );
+
+		int	max_key_size;
+		
+		if ( getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL ){
+
+			max_key_size = 255;
+			
+		}else{
+			
+			max_key_size = 64;
+		}
+		
+		key				= DHTUDPUtils.deserialiseByteArray( is, max_key_size );
 		start_position	= is.readInt();
 		length			= is.readInt();
 		total_length	= is.readInt();
@@ -99,7 +112,19 @@ DHTUDPPacketData
 		
 		os.writeByte( packet_type );
 		DHTUDPUtils.serialiseByteArray( os, transfer_key, 64 );
-		DHTUDPUtils.serialiseByteArray( os, key, 64 );
+		
+		int	max_key_size;
+		
+		if ( getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL ){
+
+			max_key_size = 255;
+			
+		}else{
+			
+			max_key_size = 64;
+		}
+		
+		DHTUDPUtils.serialiseByteArray( os, key, max_key_size );
 		os.writeInt( start_position );
 		os.writeInt( length );
 		os.writeInt( total_length );
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketHelper.java b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketHelper.java
index 88c72d0..da24969 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketHelper.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketHelper.java
@@ -62,6 +62,8 @@ DHTUDPPacketHelper
 	public static final int		ACT_DATA				= 1035;
 	public static final int		ACT_REQUEST_KEY_BLOCK	= 1036;
 	public static final int		ACT_REPLY_KEY_BLOCK		= 1037;
+	public static final int		ACT_REQUEST_QUERY_STORE	= 1038;
+	public static final int		ACT_REPLY_QUERY_STORE	= 1039;
 	
 	
 	private static boolean	registered				= false;
@@ -136,6 +138,10 @@ DHTUDPPacketHelper
 						{
 							return( new DHTUDPPacketRequestKeyBlock(network_handler,is, connection_id, transaction_id));
 						}
+						case ACT_REQUEST_QUERY_STORE:
+						{
+							return( new DHTUDPPacketRequestQueryStorage(network_handler,is, connection_id, transaction_id));
+						}
 						default:
 						{
 							throw( new IOException( "Unknown action type" ));
@@ -153,6 +159,7 @@ DHTUDPPacketHelper
 		request_decoders.put( new Integer( ACT_REQUEST_STATS ), request_decoder );		
 		request_decoders.put( new Integer( ACT_DATA ), request_decoder );
 		request_decoders.put( new Integer( ACT_REQUEST_KEY_BLOCK ), request_decoder );
+		request_decoders.put( new Integer( ACT_REQUEST_QUERY_STORE ), request_decoder );
 		
 		PRUDPPacketRequest.registerDecoders( request_decoders );	
 			
@@ -219,6 +226,10 @@ DHTUDPPacketHelper
 						{
 							return( new DHTUDPPacketReplyKeyBlock( network_handler, originator, is, transaction_id));
 						}
+						case ACT_REPLY_QUERY_STORE:
+						{
+							return( new DHTUDPPacketReplyQueryStorage( network_handler, originator, is, transaction_id));
+						}
 						default:
 						{
 							throw( new IOException( "Unknown action type" ));
@@ -236,6 +247,7 @@ DHTUDPPacketHelper
 		reply_decoders.put( new Integer( ACT_REPLY_ERROR ), reply_decoder );
 		reply_decoders.put( new Integer( ACT_REPLY_STATS ), reply_decoder );
 		reply_decoders.put( new Integer( ACT_REPLY_KEY_BLOCK ), reply_decoder );
+		reply_decoders.put( new Integer( ACT_REPLY_QUERY_STORE ), reply_decoder );
 		
 		PRUDPPacketReply.registerDecoders( reply_decoders );
 	}
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketReplyQueryStorage.java b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketReplyQueryStorage.java
new file mode 100644
index 0000000..5212a0b
--- /dev/null
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketReplyQueryStorage.java
@@ -0,0 +1,193 @@
+/*
+ * File    : PRUDPPacketReplyConnect.java
+ * Created : 20-Jan-2004
+ * By      : parg
+ * 
+ * Azureus - a Java Bittorrent client
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details ( see the LICENSE file ).
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+package com.aelitis.azureus.core.dht.transport.udp.impl;
+
+/**
+ * @author parg
+ *
+ */
+
+import java.util.*;
+
+import java.io.*;
+import java.net.InetSocketAddress;
+
+import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
+import com.aelitis.azureus.core.dht.transport.udp.impl.packethandler.DHTUDPPacketNetworkHandler;
+
+public class 
+DHTUDPPacketReplyQueryStorage
+	extends DHTUDPPacketReply
+{
+	private int					random_id;
+	private int					header_length;
+	private List<byte[]>		response;
+	
+	public
+	DHTUDPPacketReplyQueryStorage(
+		DHTTransportUDPImpl		transport,
+		int						trans_id,
+		long					conn_id,
+		DHTTransportContact		local_contact,
+		DHTTransportContact		remote_contact )
+	{
+		super( transport, DHTUDPPacketHelper.ACT_REPLY_QUERY_STORE, trans_id, conn_id, local_contact, remote_contact );
+	}
+	
+	protected
+	DHTUDPPacketReplyQueryStorage(
+		DHTUDPPacketNetworkHandler		network_handler,
+		InetSocketAddress				originator,
+		DataInputStream					is,
+		int								trans_id )
+	
+		throws IOException
+	{
+		super( network_handler, originator, is, DHTUDPPacketHelper.ACT_REPLY_QUERY_STORE, trans_id );
+		
+		short size = is.readShort();
+		
+		response = new ArrayList<byte[]>( size );
+		
+		if ( size > 0 ){
+
+			header_length = is.readByte()&0xff;
+			
+			byte[]	bitmap = new byte[size+7/8];
+
+			is.read( bitmap );
+			
+			int	pos		= 0;
+			
+			int	current	= 0;
+			
+			for (int i=0;i<size;i++){
+			
+				if ( i % 8 == 0 ){
+					
+					current = bitmap[pos++]&0xff;
+				}
+				
+				if (( current&0x80)!=0 ){
+					
+					byte[]	x = new byte[header_length];
+					
+					is.read( x );
+					
+					response.add( x );
+					
+				}else{
+					
+					response.add( null );
+				}
+				
+				current <<= 1;
+			}
+		}
+	}
+	
+	public void
+	serialise(
+		DataOutputStream	os )
+	
+		throws IOException
+	{
+		super.serialise(os);
+		
+		int	size = response.size();
+		
+		os.writeShort( size );
+
+		if ( size > 0 ){
+			
+			os.writeByte( header_length );
+			
+			byte[]	bitmap = new byte[size+7/8];
+			
+			int	bitmap_pos		= 0;
+			int	current_byte	= 0;
+			int	pos 			= 0;
+			
+			for ( byte[] x: response ){
+				
+				current_byte = current_byte << 1;
+				
+				if ( x != null){
+					
+					current_byte += 1;
+				}
+				
+				if (( pos %8 ) == 7 ){
+					
+					bitmap[bitmap_pos++] = (byte)current_byte;
+					
+					current_byte = 0;
+				}
+				
+				pos++;
+			}
+			
+			if (( pos % 8 ) != 0 ){
+				
+				bitmap[bitmap_pos++] = (byte)(current_byte << (8 - (pos % 8)));
+			}
+			
+			os.write( bitmap );
+			
+			for ( byte[] x: response ){
+
+				if ( x != null ){
+				
+					os.write( x );
+				}
+			}
+		}
+	}
+	
+	protected void
+	setRandomID(
+		int		id )
+	{
+		random_id	= id;
+	}
+	
+	protected int
+	getRandomID()
+	{
+		return( random_id );
+	}
+	
+	protected void
+	setResponse(
+		int				_header_length,
+		List<byte[]>	_response )
+	{
+		header_length	= _header_length;
+		response		= _response;
+	}
+	
+	protected List<byte[]>
+	getResponse()
+	{
+		return( response );
+	}
+}
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketRequestQueryStorage.java b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketRequestQueryStorage.java
new file mode 100644
index 0000000..02b52d7
--- /dev/null
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketRequestQueryStorage.java
@@ -0,0 +1,168 @@
+/*
+ * Created on 21-Jan-2005
+ * Created by Paul Gardner
+ * Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * 
+ * AELITIS, SAS au capital de 46,603.30 euros
+ * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
+ *
+ */
+
+package com.aelitis.azureus.core.dht.transport.udp.impl;
+
+import java.util.*;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import com.aelitis.azureus.core.dht.transport.udp.impl.packethandler.DHTUDPPacketNetworkHandler;
+
+
+/**
+ * @author parg
+ *
+ */
+
+public class 
+DHTUDPPacketRequestQueryStorage 
+	extends DHTUDPPacketRequest
+{
+	protected static final int SPACE = 
+		DHTUDPPacketHelper.PACKET_MAX_BYTES - DHTUDPPacketRequest.DHT_HEADER_SIZE - 3;
+	
+	private int						header_length;
+	private List<Object[]>			keys;
+	
+	
+	public
+	DHTUDPPacketRequestQueryStorage(
+		DHTTransportUDPImpl				_transport,
+		long							_connection_id,
+		DHTTransportUDPContactImpl		_local_contact,
+		DHTTransportUDPContactImpl		_remote_contact )
+	{
+		super( _transport, DHTUDPPacketHelper.ACT_REQUEST_QUERY_STORE, _connection_id, _local_contact, _remote_contact );
+	}
+
+	protected
+	DHTUDPPacketRequestQueryStorage(
+		DHTUDPPacketNetworkHandler		network_handler,
+		DataInputStream					is,
+		long							con_id,
+		int								trans_id )
+	
+		throws IOException
+	{
+		super( network_handler, is,  DHTUDPPacketHelper.ACT_REQUEST_QUERY_STORE, con_id, trans_id );
+		
+		header_length = is.readByte()&0xff;
+		
+		int	num_keys = is.readShort();
+		
+		keys = new ArrayList<Object[]>( num_keys );
+		
+		for (int i=0;i<num_keys;i++){
+			
+			int	prefix_length = is.readByte()&0xff;
+			
+			byte[]	prefix = new byte[prefix_length];
+			
+			is.read( prefix );
+			
+			short num_suffixes = is.readShort();
+			
+			List<byte[]> suffixes = new ArrayList<byte[]>( num_suffixes );
+			
+			keys.add( new Object[]{ prefix, suffixes });
+			
+			int	suffix_length = header_length - prefix_length;
+			
+			for (int j=0;j<num_suffixes;j++){
+				
+				byte[] suffix = new byte[ suffix_length ];
+				
+				is.read( suffix );
+				
+				suffixes.add( suffix );
+			}
+			
+		}
+		super.postDeserialise(is);
+	}
+	
+	public void
+	serialise(
+		DataOutputStream	os )
+	
+		throws IOException
+	{
+		super.serialise(os);
+		
+		os.writeByte( header_length&0xff );
+		
+		os.writeShort( keys.size());
+		
+			// add anything here be sure to adjust the SPACE above
+		
+		for ( Object[] entry: keys ){
+			
+			byte[] prefix = (byte[])entry[0];
+			
+			os.writeByte( prefix.length );
+			
+			os.write( prefix );
+			
+			List<byte[]> suffixes = (List<byte[]>)entry[1];
+			
+			os.writeShort( suffixes.size());
+			
+			for ( byte[] suffix: suffixes ){
+				
+				os.write( suffix );
+			}
+		}
+		
+		super.postSerialise( os );
+	}
+
+	protected void
+	setDetails(
+		int							_header_length,
+		List<Object[]>				_keys )
+	{
+		header_length	= _header_length;
+		keys			= _keys;
+	}
+	
+	protected int
+	getHeaderLength()
+	{
+		return( header_length );
+		
+	}
+	
+	protected List<Object[]>
+	getKeys()
+	{
+		return( keys );
+	}
+	
+	public String
+	getString()
+	{
+		return( super.getString());
+	}
+}
\ No newline at end of file
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketRequestStore.java b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketRequestStore.java
index c17fb2b..8af918a 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketRequestStore.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketRequestStore.java
@@ -78,7 +78,7 @@ DHTUDPPacketRequestStore
 		
 			// times receieved are adjusted by + skew
 				
-		value_sets 	= DHTUDPUtils.deserialiseTransportValuesArray( this, is, getClockSkew(), MAX_VALUES_PER_KEY );
+		value_sets 	= DHTUDPUtils.deserialiseTransportValuesArray( this, is, getClockSkew(), MAX_KEYS_PER_PACKET );
 		
 		super.postDeserialise(is);
 	}
@@ -99,7 +99,7 @@ DHTUDPPacketRequestStore
 		DHTUDPUtils.serialiseByteArrayArray( os, keys, MAX_KEYS_PER_PACKET );
 		
 		try{
-			DHTUDPUtils.serialiseTransportValuesArray( this, os, value_sets, 0, MAX_VALUES_PER_KEY );
+			DHTUDPUtils.serialiseTransportValuesArray( this, os, value_sets, 0, MAX_KEYS_PER_PACKET );
 			
 		}catch( DHTTransportException e ){
 			
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPUtils.java b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPUtils.java
index 73d9b03..a5969ca 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPUtils.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPUtils.java
@@ -26,7 +26,9 @@ import java.io.*;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.ArrayList;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 
 import org.gudy.azureus2.core3.util.Debug;
@@ -53,17 +55,20 @@ public class
 DHTUDPUtils 
 {
 	protected static final int	CT_UDP		= 1;
-	
-	private static ThreadLocal		tls	= 
-		new ThreadLocal()
+			
+	private static Map<String,byte[]>	node_id_history = 
+		new LinkedHashMap<String,byte[]>(128,0.75f,true)
 		{
-			public Object
-			initialValue()
+			protected boolean 
+			removeEldestEntry(
+		   		Map.Entry<String,byte[]> eldest) 
 			{
-				return( new SHA1Simple());
+				return size() > 128;
 			}
 		};
 		
+	private static SHA1Simple	hasher = new SHA1Simple();
+	
 	protected static byte[]
 	getNodeID(
 		InetSocketAddress	address,
@@ -81,26 +86,42 @@ DHTUDPUtils
 			
 		}else{
 			
-			SHA1Simple	hasher = (SHA1Simple)tls.get();
+			String	key;
 			
-			byte[]	res;
-			
-			if ( protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_RESTRICT_ID_PORTS ){
+			if ( protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_RESTRICT_ID_PORTS2 ){
+
+					// more draconian limit, analysis shows that of 500,000 node addresses only
+					// 0.01% had >= 8 ports active. ( 1% had 2 ports, 0.1% 3)
+					// Having > 1 node with the same ID doesn't actually cause too much grief
+		
+				key = ia.getHostAddress() + ":" + ( address.getPort() % 8 );
 				
+			}else if ( protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_RESTRICT_ID_PORTS ){
+
 					// limit range to around 2000 (1999 is prime)
-				
-				res = hasher.calculateHash(
-						(	ia.getHostAddress() + ":" + ( address.getPort() % 1999)).getBytes());
 
-			}else{
+				key = ia.getHostAddress() + ":" + ( address.getPort() % 1999 );
 				
-				res = hasher.calculateHash(
-							(	ia.getHostAddress() + ":" + address.getPort()).getBytes());
+			}else{
+			
+				key = ia.getHostAddress() + ":" + address.getPort();
 			}
 			
-			//System.out.println( "NodeID: " + address + " -> " + DHTLog.getString( res ));
+			synchronized( node_id_history ){
+				
+				byte[]	res = node_id_history.get( key );
+				
+				if ( res == null ){
+									
+					res = hasher.calculateHash( key.getBytes());
 			
-			return( res );
+					node_id_history.put( key, res );
+				}
+				
+				// System.out.println( "NodeID: " + address + " -> " + DHTLog.getString( res ));
+			
+				return( res );
+			}
 		}
 	}
 	
@@ -466,6 +487,17 @@ DHTUDPUtils
 			life_hours = 0;
 		}
 		
+		final byte rep_control;
+		
+		if ( packet.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL ){
+
+			rep_control = is.readByte();
+			
+		}else{
+			
+			rep_control = DHT.REP_FACT_DEFAULT;
+		}
+		
 		DHTTransportValue value = 
 			new DHTTransportValue()
 			{
@@ -511,20 +543,38 @@ DHTUDPUtils
 					return( life_hours );
 				}
 				
+				public byte
+				getReplicationControl()
+				{
+					return( rep_control );
+				}
+				
+				public byte 
+				getReplicationFactor() 
+				{
+					return( rep_control == DHT.REP_FACT_DEFAULT?DHT.REP_FACT_DEFAULT:(byte)(rep_control&0x0f));
+				}
+				
+				public byte 
+				getReplicationFrequencyHours() 
+				{
+					return( rep_control == DHT.REP_FACT_DEFAULT?DHT.REP_FACT_DEFAULT:(byte)(rep_control>>4));
+				}
+				
 				public String
 				getString()
 				{
 					long	now = SystemTime.getCurrentTime();
 					
 					return( DHTLog.getString( value_bytes ) + " - " + new String(value_bytes) + "{v=" + version + ",f=" + 
-							Integer.toHexString(flags) + ",l=" + life_hours + ",ca=" + (now - created ) + ",or=" + originator.getString() +"}" );
+							Integer.toHexString(flags) + ",l=" + life_hours + ",r=" + Integer.toHexString(getReplicationControl()) + ",ca=" + (now - created ) + ",or=" + originator.getString() +"}" );
 				}
 			};
 			
 		return( value );
 	}
 	
-	public static final int DHTTRANSPORTVALUE_SIZE_WITHOUT_VALUE	= 16 + DHTTRANSPORTCONTACT_SIZE;
+	public static final int DHTTRANSPORTVALUE_SIZE_WITHOUT_VALUE	= 17 + DHTTRANSPORTCONTACT_SIZE;
 		
 	protected static void
 	serialiseTransportValue(
@@ -563,6 +613,11 @@ DHTUDPUtils
 
 			os.writeByte( value.getLifeTimeHours()); // 14 + 2+ X + contact
 		}
+		
+		if ( packet.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL ){
+			
+			os.writeByte( value.getReplicationControl()); // 15 + 2+ X + contact
+		}
 	}
 	
 	protected static void
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/Test.java b/com/aelitis/azureus/core/dht/transport/udp/impl/Test.java
index b7b1083..a9c5a85 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/Test.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/Test.java
@@ -22,6 +22,9 @@
 
 package com.aelitis.azureus.core.dht.transport.udp.impl;
 
+import java.util.List;
+import java.util.Map;
+
 import com.aelitis.azureus.core.dht.DHT;
 import com.aelitis.azureus.core.dht.transport.*;
 import com.aelitis.azureus.core.dht.transport.udp.*;
@@ -150,6 +153,24 @@ Test
 								return 0;
 							}
 
+							public byte
+							getReplicationControl()
+							{
+								return 0;
+							}
+							
+							public byte 
+							getReplicationFactor() 
+							{
+								return 0;
+							}
+
+							public byte 
+							getReplicationFrequencyHours() 
+							{
+								return 0;
+							}
+							
 							public String
 							getString()
 							{
@@ -275,6 +296,17 @@ Test
 				});
 	}
 	
+	public DHTTransportQueryStoreReply 
+	queryStoreRequest(
+		DHTTransportContact 		contact,
+		int 						headerLen, 
+		List<Object[]>				keys) 
+	{
+		System.out.println( "TransportHandler: queryStore" );
+
+		return null;
+	}
+
 	public DHTTransportContact[]
 	findNodeRequest(
 		DHTTransportContact contact, 
diff --git a/com/aelitis/azureus/core/dht/transport/util/DHTTransportRequestCounter.java b/com/aelitis/azureus/core/dht/transport/util/DHTTransportRequestCounter.java
index 8ef41cc..c0b5b60 100644
--- a/com/aelitis/azureus/core/dht/transport/util/DHTTransportRequestCounter.java
+++ b/com/aelitis/azureus/core/dht/transport/util/DHTTransportRequestCounter.java
@@ -22,9 +22,13 @@
 
 package com.aelitis.azureus.core.dht.transport.util;
 
+import java.util.List;
+import java.util.Map;
+
 import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
 import com.aelitis.azureus.core.dht.transport.DHTTransportFindValueReply;
 import com.aelitis.azureus.core.dht.transport.DHTTransportFullStats;
+import com.aelitis.azureus.core.dht.transport.DHTTransportQueryStoreReply;
 import com.aelitis.azureus.core.dht.transport.DHTTransportRequestHandler;
 import com.aelitis.azureus.core.dht.transport.DHTTransportStoreReply;
 import com.aelitis.azureus.core.dht.transport.DHTTransportValue;
@@ -90,6 +94,17 @@ DHTTransportRequestCounter
 		return( delegate.storeRequest( contact, keys, value_sets ));
 	}
 	
+	public DHTTransportQueryStoreReply
+	queryStoreRequest(
+		DHTTransportContact 	contact, 
+		int						header_len,
+		List<Object[]>			keys )
+	{
+		stats.queryStoreReceived();
+		
+		return( delegate.queryStoreRequest( contact, header_len, keys ));
+	}
+	
 	public DHTTransportContact[]
 	findNodeRequest(
 		DHTTransportContact contact, 
diff --git a/com/aelitis/azureus/core/dht/transport/util/DHTTransportStatsImpl.java b/com/aelitis/azureus/core/dht/transport/util/DHTTransportStatsImpl.java
index 03a155c..459bf16 100644
--- a/com/aelitis/azureus/core/dht/transport/util/DHTTransportStatsImpl.java
+++ b/com/aelitis/azureus/core/dht/transport/util/DHTTransportStatsImpl.java
@@ -45,15 +45,16 @@ DHTTransportStatsImpl
 {
 	private byte	protocol_version;
 	
-	private long[]	pings		= new long[4];
-	private long[]	find_nodes	= new long[4];
-	private long[]	find_values	= new long[4];
-	private long[]	stores		= new long[4];
-	private long[]	stats		= new long[4];
-	private long[]	data		= new long[4];
-	private long[]	key_blocks	= new long[4];
-	
-	private long[]	aliens		= new long[6];
+	private long[]	pings			= new long[4];
+	private long[]	find_nodes		= new long[4];
+	private long[]	find_values		= new long[4];
+	private long[]	stores			= new long[4];
+	private long[]	stats			= new long[4];
+	private long[]	data			= new long[4];
+	private long[]	key_blocks		= new long[4];
+	private long[]	store_queries	= new long[4];
+	
+	private long[]	aliens		= new long[7];
 
 	private long	incoming_requests;
 	private long	outgoing_requests;
@@ -102,6 +103,7 @@ DHTTransportStatsImpl
 		add( stats, other.stats );
 		add( data, other.data );
 		add( key_blocks, other.key_blocks );
+		add( store_queries, other.store_queries );
 		add( aliens, other.aliens );
 		
 		incoming_requests += other.incoming_requests;
@@ -128,6 +130,7 @@ DHTTransportStatsImpl
 		clone.stores		= (long[])stores.clone();
 		clone.data			= (long[])data.clone();
 		clone.key_blocks	= (long[])key_blocks.clone();
+		clone.store_queries	= (long[])store_queries.clone();
 		clone.aliens		= (long[])aliens.clone();
 		
 		clone.incoming_requests	= incoming_requests;
@@ -198,6 +201,41 @@ DHTTransportStatsImpl
 		return( key_blocks );
 	}
 	
+		// store queries
+	
+	public void
+	queryStoreSent(
+		DHTUDPPacketRequest	request )
+	{
+		store_queries[STAT_SENT]++;
+					
+		outgoingRequestSent( request );
+	}
+	
+	public void
+	queryStoreOK()
+	{
+		store_queries[STAT_OK]++;
+	}
+	
+	public void
+	queryStoreFailed()
+	{
+		store_queries[STAT_FAILED]++;
+	}
+	
+	public void
+	queryStoreReceived()
+	{
+		store_queries[STAT_RECEIVED]++;
+	}
+	
+	public long[]
+	getQueryStores()
+	{
+		return( store_queries );
+	}
+	
 		// find node
 	
 	public void
@@ -436,6 +474,10 @@ DHTTransportStatsImpl
 			}else if ( type == DHTUDPPacketHelper.ACT_REQUEST_KEY_BLOCK ){
 				
 				aliens[AT_KEY_BLOCK]++;
+				
+			}else if ( type == DHTUDPPacketHelper.ACT_REQUEST_QUERY_STORE ){
+				
+				aliens[AT_QUERY_STORE]++;
 			}
 		}
 		
diff --git a/com/aelitis/azureus/core/diskmanager/cache/CacheFile.java b/com/aelitis/azureus/core/diskmanager/cache/CacheFile.java
index 9613986..f0cd910 100644
--- a/com/aelitis/azureus/core/diskmanager/cache/CacheFile.java
+++ b/com/aelitis/azureus/core/diskmanager/cache/CacheFile.java
@@ -34,8 +34,9 @@ import org.gudy.azureus2.core3.util.DirectByteBuffer;
 public interface 
 CacheFile 
 {
-	public static final int	CT_LINEAR	= 1;
-	public static final int CT_COMPACT	= 2;
+	public static final int	CT_LINEAR			= 1;
+	public static final int CT_COMPACT			= 2;
+	public static final int CT_PIECE_REORDER	= 3;
 
 	public static final int	CF_READ		= 1;
 	public static final int CF_WRITE	= 2;
@@ -98,6 +99,13 @@ CacheFile
 		throws CacheFileManagerException;
 	
 	public void
+	setPieceComplete(
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws CacheFileManagerException;
+	
+	public void
 	read(
 		DirectByteBuffer	buffer,
 		long				offset,
diff --git a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileManagerImpl.java b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileManagerImpl.java
index d9bb452..94b2e6f 100644
--- a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileManagerImpl.java
+++ b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileManagerImpl.java
@@ -61,6 +61,42 @@ CacheFileManagerImpl
 		}
 	}
 	
+	protected static int
+	convertCacheToFileType(
+		int	cache_type )
+	{
+		if ( cache_type == CacheFile.CT_LINEAR ){
+			
+			return( FMFile.FT_LINEAR );
+			
+		}else if ( cache_type == CacheFile.CT_COMPACT ){
+			
+			return( FMFile.FT_COMPACT );
+			
+		}else{
+			
+			return( FMFile.FT_PIECE_REORDER );
+		}
+	}
+	
+	protected static int
+	convertFileToCacheType(
+		int	file_type )
+	{
+		if ( file_type == FMFile.FT_LINEAR ){
+			
+			return( CacheFile.CT_LINEAR );
+			
+		}else if ( file_type == FMFile.FT_COMPACT ){
+			
+			return( CacheFile.CT_COMPACT );
+			
+		}else{
+			
+			return( CacheFile.CT_PIECE_REORDER );
+		}
+	}
+	
 	protected boolean	cache_enabled;
 	protected boolean	cache_read_enabled;
 	protected boolean	cache_write_enabled;
@@ -203,6 +239,8 @@ CacheFileManagerImpl
 			this_mon.exit();
 		}
 		
+		int	fm_type = convertCacheToFileType( type );
+		
 		try{
 			FMFile	fm_file	= 
 				file_manager.createFile(
@@ -223,8 +261,7 @@ CacheFileManagerImpl
 						{
 							return( owner.getCacheFileControlFileDir( ));
 						}
-					}, file,
-					type==CacheFile.CT_LINEAR?FMFile.FT_LINEAR:FMFile.FT_COMPACT );
+					}, file, fm_type );
 				
 			TOTorrentFile	tf = owner.getCacheFileTorrentFile();
 			
diff --git a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithCache.java b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithCache.java
index 7061478..677eae4 100644
--- a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithCache.java
+++ b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithCache.java
@@ -1388,7 +1388,7 @@ CacheFileWithCache
 				flushCachePublic( false, -1 );
 			}
 			
-			file.setStorageType( type==CT_COMPACT?FMFile.FT_COMPACT:FMFile.FT_LINEAR );
+			file.setStorageType( CacheFileManagerImpl.convertCacheToFileType( type ));
 			
 		}catch( FMFileManagerException e ){
 			
@@ -1403,7 +1403,7 @@ CacheFileWithCache
 	public int
 	getStorageType()
 	{
-		return( file.getStorageType()==FMFile.FT_COMPACT?CT_COMPACT:CT_LINEAR );
+		return( CacheFileManagerImpl.convertFileToCacheType( file.getStorageType()));
 	}
 
 	public long
@@ -1519,6 +1519,22 @@ CacheFileWithCache
 	}
 	
 	public void
+	setPieceComplete(
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws CacheFileManagerException
+	{
+		try{
+			file.setPieceComplete( piece_number, piece_data );
+			
+		}catch( FMFileManagerException e ){
+			
+			manager.rethrow(this,e);
+		}
+	}
+	
+	public void
 	read(
 		DirectByteBuffer[]	buffers,
 		long				position,
diff --git a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithoutCache.java b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithoutCache.java
index a1de815..0d75f9b 100644
--- a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithoutCache.java
+++ b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithoutCache.java
@@ -128,7 +128,7 @@ CacheFileWithoutCache
 	{
 		try{
 			
-			file.setStorageType( type==CT_COMPACT?FMFile.FT_COMPACT:FMFile.FT_LINEAR );
+			file.setStorageType( CacheFileManagerImpl.convertCacheToFileType( type ));
 			
 		}catch( FMFileManagerException e ){
 			
@@ -139,7 +139,7 @@ CacheFileWithoutCache
 	public int
 	getStorageType()
 	{
-		return( file.getStorageType()==FMFile.FT_COMPACT?CT_COMPACT:CT_LINEAR );
+		return( CacheFileManagerImpl.convertFileToCacheType( file.getStorageType()));
 	}
 
 	public long
@@ -185,6 +185,22 @@ CacheFileWithoutCache
 	}
 	
 	public void
+	setPieceComplete(
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws CacheFileManagerException
+	{
+		try{
+			file.setPieceComplete( piece_number, piece_data );
+			
+		}catch( FMFileManagerException e ){
+			
+			manager.rethrow(this,e);
+		}
+	}
+	
+	public void
 	read(
 		DirectByteBuffer[]	buffers,
 		long				position,
diff --git a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithoutCacheMT.java b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithoutCacheMT.java
index 371444e..2abce0f 100644
--- a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithoutCacheMT.java
+++ b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithoutCacheMT.java
@@ -276,7 +276,7 @@ CacheFileWithoutCacheMT
 	public int
 	getStorageType()
 	{
-		return( base_file.getStorageType()==FMFile.FT_COMPACT?CT_COMPACT:CT_LINEAR );
+		return( CacheFileManagerImpl.convertFileToCacheType( base_file.getStorageType()));
 	}
 
 	public long
@@ -320,6 +320,22 @@ CacheFileWithoutCacheMT
 		}
 	}
 	
+	public void
+	setPieceComplete(
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws CacheFileManagerException
+	{
+		try{
+			base_file.setPieceComplete( piece_number, piece_data );
+			
+		}catch( FMFileManagerException e ){
+			
+			manager.rethrow(this,e);
+		}
+	}
+	
 	protected FMFile
 	getFile()
 	
diff --git a/com/aelitis/azureus/core/diskmanager/cache/impl/Test.java b/com/aelitis/azureus/core/diskmanager/cache/impl/Test.java
index bb3c0f2..dfdc8b5 100644
--- a/com/aelitis/azureus/core/diskmanager/cache/impl/Test.java
+++ b/com/aelitis/azureus/core/diskmanager/cache/impl/Test.java
@@ -23,8 +23,16 @@
 package com.aelitis.azureus.core.diskmanager.cache.impl;
 
 import java.io.*;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
 
 
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
 import org.gudy.azureus2.core3.torrent.TOTorrentFile;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.core3.logging.*;
@@ -61,7 +69,7 @@ Test
 			
 			manager.initialise( true, true, true, 10*1024*1024, 1024 );
 
-			new Test().writeTest(manager);
+			new Test().pieceReorderTest(manager);
 			
 		}catch( Throwable e ){
 			
@@ -70,6 +78,537 @@ Test
 	}
 	
 	public void
+	pieceReorderTest(
+		CacheFileManagerImpl	manager )
+	{
+		try{
+			Random random = new Random(0);
+			
+			int	num_files 	= 100;
+			int	piece_size	= 1024;
+			int file_size_average	= piece_size*30;
+			
+			int	chunk_fixed_size 	= 0;
+			int chunk_random_size	= 1024;
+			
+			int	write_order	= 2;		// 0 = linear forwards; 1 = linear backwards; 2 = random;
+			
+			
+			
+			int[]	file_sizes = new int[num_files];
+			
+			for ( int i=0;i<num_files;i++){
+				
+				file_sizes[i] = random.nextInt( 2*file_size_average ) + 1;
+			}
+		
+			final File	control_dir		= new File("C:\\temp\\filetestcontrol" );
+			
+			FileUtil.recursiveDelete( control_dir );
+			
+			control_dir.mkdirs();
+	
+			File	torrent_file 	= new File("C:\\temp\\filetest.torrent" );
+			
+			torrent_file.delete();
+			
+			File	source_file_or_dir;
+			File	target_file_or_dir;
+			
+			if ( num_files == 1 ){
+				
+				source_file_or_dir = new File("C:\\temp\\filetest1.dat" );
+				target_file_or_dir = new File("C:\\temp\\filetest2.dat" );
+				
+				source_file_or_dir.delete();
+				target_file_or_dir.delete();
+			}else{
+				
+				source_file_or_dir = new File("C:\\temp\\filetest1.dir" );
+				target_file_or_dir = new File("C:\\temp\\filetest2.dir" );
+				
+				FileUtil.recursiveDelete( source_file_or_dir );
+				FileUtil.recursiveDelete( target_file_or_dir );
+				
+				source_file_or_dir.mkdirs();
+				target_file_or_dir.mkdirs();
+			}
+			
+			File[]	source_files = new File[ num_files ];
+			File[]	target_files = new File[ num_files ];
+			
+			RandomAccessFile[]	source_file_rafs = new RandomAccessFile[ num_files ];
+			
+			final TOTorrent torrent;
+			
+			for ( int i=0; i<num_files; i++ ){
+				
+				File	source_file;
+				File	target_file;
+				
+				if  ( num_files == 1 ){
+					
+					source_file = source_file_or_dir;
+					target_file = target_file_or_dir;
+					
+				}else{
+					
+					source_file = new File( source_file_or_dir, "file" + i );
+					target_file = new File( target_file_or_dir, "file" + i );
+				}
+				
+				source_files[i] = source_file;
+				target_files[i]	= target_file;
+				
+				FileOutputStream fos = new FileOutputStream( source_file );
+				
+				byte[]	buffer = new byte[64*1024];
+				
+				int	rem = file_sizes[i];
+				
+				while( rem > 0 ){
+				
+					random.nextBytes( buffer );
+				
+					int	to_write = rem>buffer.length?buffer.length:rem;
+					
+					fos.write( buffer, 0, to_write );
+					
+					rem -= to_write;
+				}
+				
+				fos.close();
+				
+				source_file_rafs[i] = new RandomAccessFile( source_file, "r" );
+			}
+			
+			torrent = 
+					TOTorrentFactory.createFromFileOrDirWithFixedPieceLength(
+						source_file_or_dir,
+						new URL( "http://a.b.c/" ),
+						piece_size ).create();
+			
+			final TOTorrentFile[] torrent_files = torrent.getFiles();
+			
+				// unfortunately the torrent's file order may not be ours...
+			
+			for ( int i=0;i<torrent_files.length;i++){
+
+				TOTorrentFile tf = torrent_files[i];
+				
+				String rel_path = tf.getRelativePath();
+				
+				boolean	found = false;
+				
+				for (int j=0;j<source_files.length;j++){
+					
+					if ( source_files[j].getName().equals( rel_path )){
+				
+						found = true;
+					
+						if ( j != i ){
+							
+							int	temp = file_sizes[i];
+							file_sizes[i] = file_sizes[j];
+							file_sizes[j] = temp;
+							
+							File femp = source_files[i];
+							source_files[i] = source_files[j];
+							source_files[j] = femp;
+							
+							femp = target_files[i];
+							target_files[i] = target_files[j];
+							target_files[j] = femp;
+							
+							RandomAccessFile remp = source_file_rafs[i];
+							source_file_rafs[i] = source_file_rafs[j];
+							source_file_rafs[j] = remp;
+						}
+						break;
+					}
+				}
+
+				if ( !found ){
+					
+					Debug.out( "eh?" );
+					
+					return;
+				}
+			}
+			
+			CacheFile[] cache_files = new CacheFile[ torrent_files.length ];
+			
+			for ( int i=0;i<torrent_files.length;i++){
+				
+				final int f_i = i;
+				
+				File target_file		= target_files[i];
+				final File source_file	= source_files[i];
+				
+				
+				System.out.println( "file " + i + ": e_size=" + file_sizes[i] + ", t_size=" + torrent_files[i].getLength() + ", d_size=" + source_file.length());
+				
+				cache_files[i] = manager.createFile(
+					new CacheFileOwner()
+					{
+						public String
+						getCacheFileOwnerName()
+						{
+							return( source_file.getAbsolutePath());
+						}
+						
+						public TOTorrentFile
+						getCacheFileTorrentFile()
+						{
+							return( torrent_files[f_i] );
+						}
+						public File 
+						getCacheFileControlFileDir() 
+						{
+							return( control_dir );
+						}
+   						public int
+						getCacheMode()
+						{
+							return( CacheFileOwner.CACHE_MODE_NO_CACHE );
+						}
+					},
+					target_file, CacheFile.CT_PIECE_REORDER );
+			
+				cache_files[i].setAccessMode( CacheFile.CF_WRITE );
+			}
+			
+			List<Chunk> chunks = new ArrayList<Chunk>();
+			
+			List<Chunk>[] piece_map = new List[ torrent.getNumberOfPieces()];
+			
+			{
+				long	pos 			= 0;
+				int		file_index		= 0;
+				long	file_offset		= 0;
+				
+				long	total_size 	= torrent.getSize();
+				long	rem			= total_size;
+				
+	
+				while( rem > 0 ){
+					
+					long chunk_length;
+					
+					if ( chunk_fixed_size != 0 ){
+						
+						chunk_length = chunk_fixed_size;
+						
+					}else{
+						
+						chunk_length = random.nextInt( chunk_random_size ) + 1;
+					}
+					
+					if ( rem < chunk_length ){
+						
+						chunk_length = (int)rem;
+					}
+									
+					List<ChunkSlice> slices = new ArrayList<ChunkSlice>();
+					
+					Chunk chunk = new Chunk( pos, chunk_length, slices );
+					
+					chunks.add( chunk );
+						
+					while( chunk_length > 0 ){
+					
+						long	file_size = file_sizes[ file_index ];
+	
+						long 	file_rem = file_size - file_offset;
+						
+						long	avail = Math.min( file_rem, chunk_length );
+						
+						if ( avail > 0 ){
+			
+							int	piece_start	= (int)( pos/piece_size );
+
+							rem -= avail;
+							pos	+= avail;
+
+							int	piece_end	= (int)((pos-1)/piece_size );
+							
+							slices.add( new ChunkSlice( file_index, file_offset, avail, piece_start, piece_end ));
+						}
+						
+						chunk_length -= avail;
+			
+						if ( chunk_length > 0 ){
+							
+							file_offset	= 0;
+							
+							file_index++;
+							
+						}else{
+							
+							file_offset += avail;
+							
+							break;
+						}
+					}
+					
+					int	piece_start = slices.get(0).getPieceStart();
+					int	piece_end 	= slices.get(slices.size()-1).getPieceEnd();
+					
+					for (int i=piece_start;i<=piece_end;i++){
+						
+						if ( piece_map[i] == null ){
+							
+							piece_map[i] = new ArrayList<Chunk>();
+						}
+						
+						piece_map[i].add( chunk );
+					}
+					
+					chunk.setPieces( piece_start, piece_end );				
+
+					System.out.println( chunk.getString());		
+				}
+			}
+			
+			for (int i=0;i<piece_map.length;i++){
+				
+				System.out.println( i + ": " + piece_map[i].size());
+			}
+			
+			while ( chunks.size() > 0 ){
+				
+				Chunk chunk;
+				
+				if ( write_order == 0 ){
+					
+					chunk = chunks.remove( 0 );
+					
+				}else if ( write_order == 1 ){
+						
+					chunk = chunks.remove( chunks.size() - 1 );
+						
+				}else{
+					
+					chunk = chunks.remove( random.nextInt( chunks.size()));
+				}
+				
+				System.out.println( "Processing chunk " + chunk.getString());
+				
+				List<ChunkSlice> slices = new ArrayList<ChunkSlice>( chunk.getSlices());
+				
+				if ( write_order == 1 ){
+					
+					Collections.reverse( slices );
+				}
+				
+				for ( ChunkSlice slice: slices ){
+					
+					int		file_index 	= slice.getFileIndex();
+					long	file_offset	= slice.getFileOffset();
+					long	length		= slice.getLength();
+					
+
+					System.out.println( "Processing slice " + slice.getString() + "[file size=" + file_sizes[file_index]);
+					
+					DirectByteBuffer	buffer = DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_OTHER, (int)length );
+					
+					try{
+						RandomAccessFile raf = source_file_rafs[ file_index ];
+						
+						raf.seek( file_offset );
+						
+						raf.getChannel().read( buffer.getBuffer( DirectByteBuffer.SS_EXTERNAL ));
+						
+						buffer.flip( DirectByteBuffer.SS_EXTERNAL );
+						
+						cache_files[file_index].write( buffer, file_offset );
+					
+					}finally{
+						
+						buffer.returnToPool();
+					}
+				}
+				
+				chunk.setDone();
+				
+				int	chunk_piece_start 	= chunk.getPieceStart();
+				int	chunk_piece_end		= chunk.getPieceEnd();
+				
+				for ( int i=chunk_piece_start;i<=chunk_piece_end;i++){
+					
+					List<Chunk> pieces = piece_map[i];
+					
+					boolean complete = true;
+					
+					for ( Chunk c: pieces ){
+						
+						if ( !c.isDone()){
+							
+							complete = false;
+							
+							break;
+						}
+					}
+					
+					if ( complete ){
+						
+						for ( ChunkSlice slice: slices ){
+
+							if ( i >= slice.getPieceStart() && i <= slice.getPieceEnd()){
+
+								long	piece_offset = i*piece_size;
+								int		piece_length;
+
+								if ( i < piece_map.length - 1 ){
+									
+									piece_length = piece_size;
+									
+								}else{
+									
+									long	total = torrent.getSize();
+									
+									piece_length = (int)( total - ( total/piece_size )*piece_size );
+									
+									if ( piece_length == 0 ){
+										
+										piece_length = piece_size;
+									}
+								}
+														
+								DirectByteBuffer	piece_data = 
+									DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_OTHER, piece_length );
+
+								long	pos			= 0;
+								int		file_index	= 0;
+								int		rem			= piece_length;
+								
+								while( rem > 0 ){
+									
+									long	file_size = file_sizes[ file_index ];
+									
+									long	file_end = pos + file_size;
+									
+									long	avail = file_end - piece_offset;
+
+									if ( avail > 0 ){
+										
+										int	to_use = (int)Math.min( avail, rem );
+										
+										long file_offset = piece_offset - pos;
+										
+										int	lim = piece_data.limit( DirectByteBuffer.AL_OTHER );
+										
+										piece_data.limit( DirectByteBuffer.AL_OTHER, piece_data.position( DirectByteBuffer.AL_OTHER ) + to_use );
+										
+										cache_files[ file_index ].read( piece_data, file_offset, CacheFile.CP_NONE );
+										
+										piece_data.limit( DirectByteBuffer.AL_OTHER, lim );
+
+										piece_offset += to_use;
+										
+										rem -= to_use;
+									}
+									
+									file_index++;
+									
+									pos += file_size;
+								}
+								
+								try{
+									cache_files[ slice.getFileIndex()].setPieceComplete(
+										i,
+										piece_data );	
+									
+								}finally{
+									
+									piece_data.returnToPool();
+								}
+							}
+						}
+					}
+				}
+			}
+			
+			for (int i=0;i<num_files;i++){
+				
+				source_file_rafs[i].close();
+				
+				cache_files[i].close();
+				
+				byte[]	buffer1 = new byte[256*1024];
+				byte[]	buffer2 = new byte[256*1024];
+				
+				if ( source_files[i].length() != target_files[i].length()){
+					
+					System.err.println( "File sizes differ for " + i );
+				}
+				
+				FileInputStream	fis1 = new FileInputStream( source_files[i] );
+				FileInputStream	fis2 = new FileInputStream( target_files[i] );
+				
+				long	len = file_sizes[i];
+				long	pos	= 0;
+				
+				boolean	failed = false;
+				
+				while( len > 0 ){
+					
+					int	avail = (int)Math.min( len, buffer1.length );
+					
+					int r1 = fis1.read( buffer1, 0, avail );
+					int r2 = fis2.read( buffer2, 0, avail );
+					
+					if ( r1 != r2 ){
+						
+						System.err.println( "read lens different: file=" + i + ",pos=" + pos );
+						
+						failed = true;
+						
+						break;
+						
+					}else{
+						
+						if ( Arrays.equals( buffer1, buffer2 )){
+							
+							len -= r1;
+							pos += r1;
+						}else{
+							
+							int diff_at = -1;
+							
+							for (int j=0;j<avail;j++){
+								
+								if ( buffer1[j] != buffer2[j] ){
+									
+									diff_at = j;
+									
+									break;
+								}
+							}
+							
+							System.err.println( "mismatch: file=" + i + ",pos=" + pos + " + " + diff_at );
+							
+							failed = true;
+							
+							break;
+						}
+					}
+				}
+				
+				if ( !failed ){
+					
+					System.out.println( "file " + i + ": matched " + pos + " of " + file_sizes[i] );
+					
+				}
+			}
+			
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+		}
+	}
+	
+	public void
 	writeTest(
 		CacheFileManagerImpl	manager )
 	{
@@ -354,4 +893,143 @@ Test
 	{
 		return( (int)(Math.random()*num ));
 	}
+	
+	protected static class
+	Chunk
+	{
+		private long				offset;
+		private long				length;
+		private List<ChunkSlice>	slices;
+		
+		private int					piece_start;
+		private int					piece_end;
+		
+		private boolean				is_done;
+		
+		protected
+		Chunk(
+			long				_offset,
+			long				_length,
+			List<ChunkSlice>	_slices )
+		{
+			offset	= _offset;
+			length	= _length;
+			slices	= _slices;
+		}
+		
+		protected List<ChunkSlice>
+		getSlices()
+		{
+			return( slices );
+		}
+		
+		protected void
+		setPieces(
+			int		_piece_start,
+			int		_piece_end )
+		{
+			piece_start	= _piece_start;
+			piece_end	= _piece_end;
+		}
+		
+		protected int
+  		getPieceStart()
+  		{
+  			return( piece_start );
+  		}
+		
+		protected int
+  		getPieceEnd()
+  		{
+			return( piece_end );
+  		}
+		
+		protected void
+		setDone()
+		{
+			is_done	= true;
+		}
+		
+		protected boolean
+		isDone()
+		{
+			return( is_done );
+		}
+		
+		protected String
+		getString()
+		{
+			String	str = "";
+			
+			for ( ChunkSlice s: slices ){
+				
+				str += (str.length()==0?"":",") + s.getString();
+			}
+			
+			return( "offset=" + offset + ",length=" + length + ",slices={" + str + "}" );
+		}
+	}
+	
+	protected static class
+	ChunkSlice
+	{
+		private int		file_index;
+		private long	file_offset;
+		private long	length;
+		
+		private int		piece_start;
+		private int		piece_end;
+		
+		protected
+		ChunkSlice(
+			int		_file_index,
+			long	_file_offset,
+			long	_length,
+			int		_piece_start,
+			int		_piece_end )
+		{
+			file_index	= _file_index;
+			file_offset	= _file_offset;
+			length		= _length;
+			
+			piece_start	= _piece_start;
+			piece_end	= _piece_end;
+		}
+		
+		protected int
+		getFileIndex()
+		{
+			return( file_index );
+		}
+		
+		protected long
+		getFileOffset()
+		{
+			return( file_offset );
+		}
+		
+		protected long
+		getLength()
+		{
+			return( length );
+		}
+		
+		protected int
+		getPieceStart()
+		{
+			return( piece_start );
+		}
+		
+		protected int
+		getPieceEnd()
+		{
+			return( piece_end );
+		}
+		
+		protected String
+		getString()
+		{
+			return( "fi=" + file_index + ",fo=" + file_offset + ",len=" + length + ",ps=" + piece_start + ",pe=" + piece_end);
+		}
+	}
 }
diff --git a/com/aelitis/azureus/core/diskmanager/file/FMFile.java b/com/aelitis/azureus/core/diskmanager/file/FMFile.java
index 798e245..1e9853e 100644
--- a/com/aelitis/azureus/core/diskmanager/file/FMFile.java
+++ b/com/aelitis/azureus/core/diskmanager/file/FMFile.java
@@ -34,8 +34,9 @@ import org.gudy.azureus2.core3.util.DirectByteBuffer;
 public interface 
 FMFile 
 {
-	public static final int	FT_LINEAR	= 1;
-	public static final int	FT_COMPACT	= 2;
+	public static final int	FT_LINEAR			= 1;
+	public static final int	FT_COMPACT			= 2;
+	public static final int	FT_PIECE_REORDER	= 3;
 	
 	public static final int	FM_READ		= 1;
 	public static final int FM_WRITE	= 2;
@@ -97,6 +98,13 @@ FMFile
 		throws FMFileManagerException;
 	
 	public void
+	setPieceComplete(
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws FMFileManagerException;
+	
+	public void
 	read(
 		DirectByteBuffer	buffer,
 		long				offset )
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccess.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccess.java
index f135981..a24b9c8 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccess.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccess.java
@@ -26,12 +26,16 @@ import java.io.RandomAccessFile;
 
 import org.gudy.azureus2.core3.util.DirectByteBuffer;
 
-import com.aelitis.azureus.core.diskmanager.file.FMFile;
 import com.aelitis.azureus.core.diskmanager.file.FMFileManagerException;
 
 public interface 
 FMFileAccess 
 {
+	public void
+	aboutToOpen()
+	
+		throws FMFileManagerException;
+		
 	public long
 	getLength(
 		RandomAccessFile		raf )
@@ -47,7 +51,6 @@ FMFileAccess
 	
 	public void
 	read(
-		FMFile				file,
 		RandomAccessFile	raf,
 		DirectByteBuffer[]	buffers,
 		long				offset )
@@ -67,6 +70,14 @@ FMFileAccess
 	
 		throws FMFileManagerException;
 	
+	public void
+	setPieceComplete(
+		RandomAccessFile	raf,
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws FMFileManagerException;
+	
 	public String
 	getString();
 }
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessCompact.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessCompact.java
index 649e439..fcfdacf 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessCompact.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessCompact.java
@@ -32,7 +32,6 @@ import org.gudy.azureus2.core3.torrent.TOTorrentFile;
 import org.gudy.azureus2.core3.util.DirectByteBuffer;
 import org.gudy.azureus2.core3.util.FileUtil;
 
-import com.aelitis.azureus.core.diskmanager.file.FMFile;
 import com.aelitis.azureus.core.diskmanager.file.FMFileManagerException;
 
 public class 
@@ -61,15 +60,15 @@ FMFileAccessCompact
 	protected
 	FMFileAccessCompact(
 		TOTorrentFile	_torrent_file,
-		File			controlFileDir,
-		String			controlFileName,
+		File			_controlFileDir,
+		String			_controlFileName,
 		FMFileAccess	_delegate )
 	
 		throws FMFileManagerException
 	{
 		torrent_file	= _torrent_file;
-		this.controlFileDir	= controlFileDir;
-		this.controlFileName = controlFileName;
+		controlFileDir	= _controlFileDir;
+		controlFileName = _controlFileName;
 		delegate		= _delegate;
 
 		try{
@@ -171,6 +170,14 @@ FMFileAccessCompact
 		return( last_piece_length );
 	}
 	
+	public void
+	aboutToOpen()
+	
+		throws FMFileManagerException
+	{
+		delegate.aboutToOpen();
+	}
+	
 	public long
 	getLength(
 		RandomAccessFile		raf )
@@ -196,7 +203,6 @@ FMFileAccessCompact
 	
 	protected void
 	read(
-		FMFile				file,
 		RandomAccessFile	raf,
 		DirectByteBuffer	buffer,
 		long				position )
@@ -222,7 +228,7 @@ FMFileAccessCompact
 					
 					// System.out.println( "    all in first piece" );
 
-					delegate.read( file, raf, new DirectByteBuffer[]{ buffer }, position );
+					delegate.read( raf, new DirectByteBuffer[]{ buffer }, position );
 					
 					position	+= len;
 					len			= 0;
@@ -234,7 +240,7 @@ FMFileAccessCompact
 
 					buffer.limit( SS, buffer.position(SS) + available );
 					
-					delegate.read( file, raf, new DirectByteBuffer[]{ buffer }, position );
+					delegate.read( raf, new DirectByteBuffer[]{ buffer }, position );
 				
 					buffer.limit( SS, original_limit );
 					
@@ -287,7 +293,7 @@ FMFileAccessCompact
 			
 			// System.out.println( "    some in last piece" );
 
-			delegate.read( file, raf, new DirectByteBuffer[]{ buffer }, ( position - last_piece_start ) + first_piece_length );
+			delegate.read( raf, new DirectByteBuffer[]{ buffer }, ( position - last_piece_start ) + first_piece_length );
 			
 		}finally{
 			
@@ -297,7 +303,6 @@ FMFileAccessCompact
 	
 	public void
 	read(
-		FMFile					file,
 		RandomAccessFile		raf,
 		DirectByteBuffer[]		buffers,
 		long					position )
@@ -310,7 +315,7 @@ FMFileAccessCompact
 			
 			int	len = buffers[i].limit(SS) - buffers[i].position(SS);
 		
-			read( file, raf, buffer, position );
+			read( raf, buffer, position );
 			
 			position += len;
 		}
@@ -455,6 +460,16 @@ FMFileAccessCompact
 		writeState();
 	}
 	
+	public void
+	setPieceComplete(
+		RandomAccessFile	raf,
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws FMFileManagerException
+	{	
+	}
+	
 	protected void
 	readState()
 	
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessController.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessController.java
index 393ca9c..e009129 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessController.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessController.java
@@ -30,6 +30,7 @@ import org.gudy.azureus2.core3.torrent.TOTorrentFile;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.DirectByteBuffer;
 import org.gudy.azureus2.core3.util.DirectByteBufferPool;
+import org.gudy.azureus2.core3.util.StringInterner;
 
 import com.aelitis.azureus.core.diskmanager.file.FMFile;
 import com.aelitis.azureus.core.diskmanager.file.FMFileManagerException;
@@ -38,6 +39,8 @@ public class
 FMFileAccessController
 	implements FMFileAccess
 {
+	private static final String REORDER_SUFFIX = ".2";
+	
 	private FMFileImpl	owner;
 	
 	private int		type		= FMFile.FT_LINEAR;
@@ -54,6 +57,8 @@ FMFileAccessController
 	
 		throws FMFileManagerException
 	{
+		// _target_type = FMFile.FT_PIECE_REORDER;
+		
 		owner		= _file;
 		
 		// actual file shouldn't exist for change to occur - it is the responsibility
@@ -80,22 +85,47 @@ FMFileAccessController
 
 		}else{
 		
-			boolean	control_file_existed = new File(controlPath,controlFileName).exists();
+			if ( new File( controlPath, controlFileName ).exists()){
+				
+				type = FMFile.FT_COMPACT;
+				
+			}else if ( new File( controlPath, controlFileName + REORDER_SUFFIX ).exists()){
 			
-			type = control_file_existed?FMFile.FT_COMPACT:FMFile.FT_LINEAR;
+				type = FMFile.FT_PIECE_REORDER;
+				
+			}else{
+				
+				if ( _target_type == FMFile.FT_PIECE_REORDER && !owner.getLinkedFile().exists()){
+					
+					type = FMFile.FT_PIECE_REORDER;
+					
+				}else{
+					
+					type = FMFile.FT_LINEAR;
+				}
+			}
 						
 			if ( type == FMFile.FT_LINEAR ){
 				
 				file_access = new FMFileAccessLinear( owner );
 				
-			}else{
+			}else if ( type == FMFile.FT_COMPACT ){
 				
 				file_access = 
 					new FMFileAccessCompact(
-							owner.getOwner().getTorrentFile(),controlPath,
+							owner.getOwner().getTorrentFile(),
+							controlPath,
 							controlFileName,  
 							new FMFileAccessLinear( owner ));
-			}				
+			}else{
+				
+				file_access = 
+					new FMFileAccessPieceReorderer(
+							owner.getOwner().getTorrentFile(),
+							controlPath,
+							controlFileName + REORDER_SUFFIX,  
+							new FMFileAccessLinear( owner ));
+			}
 			
 			if ( type != _target_type ){
 				
@@ -110,6 +140,11 @@ FMFileAccessController
 	
 		throws FMFileManagerException
 	{
+		if ( type == FMFile.FT_PIECE_REORDER || target_type == FMFile.FT_PIECE_REORDER ){
+			
+			throw( new FMFileManagerException( "Conversion to/from piece-reorder not supported" ));
+		}
+		
 		File	file = owner.getLinkedFile();
 			
 		RandomAccessFile raf = null;
@@ -172,7 +207,7 @@ FMFileAccessController
 					
 					try{
 					
-						file_access.read( owner, raf, new DirectByteBuffer[]{ buffer }, last_piece_start );
+						file_access.read( raf, new DirectByteBuffer[]{ buffer }, last_piece_start );
 						
 							// see if we need to truncate
 						
@@ -300,13 +335,12 @@ FMFileAccessController
 			Debug.out("File '" + owner.getName() + "' not found in torrent!" );
 			
 			controlFileName = null;
-			controlPath = null;
+			controlPath 	= null;
 			
 		}else{
 			
-			controlPath = owner.getOwner().getControlFileDir( );
-			controlFileName =  "fmfile" + file_index + ".dat";
-			
+			controlPath 	= owner.getOwner().getControlFileDir( );
+			controlFileName =  StringInterner.intern("fmfile" + file_index + ".dat");
 		}
 	}
 	
@@ -334,6 +368,14 @@ FMFileAccessController
 	
 		// FileAccess
 	
+	public void
+	aboutToOpen()
+	
+		throws FMFileManagerException
+	{
+		file_access.aboutToOpen();
+	}
+	
 	public long
 	getLength(
 		RandomAccessFile		raf )
@@ -354,15 +396,25 @@ FMFileAccessController
 	}
 	
 	public void
+	setPieceComplete(
+		RandomAccessFile	raf,
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws FMFileManagerException
+	{
+		file_access.setPieceComplete( raf, piece_number, piece_data );
+	}
+	
+	public void
 	read(
-		FMFile				file,
 		RandomAccessFile	raf,
 		DirectByteBuffer[]	buffers,
 		long				offset )
 	
 		throws FMFileManagerException
 	{
-		file_access.read( file, raf, buffers, offset );
+		file_access.read( raf, buffers, offset );
 	}
 	
 	public void
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessLinear.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessLinear.java
index d8b8005..06663c2 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessLinear.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessLinear.java
@@ -57,6 +57,13 @@ FMFileAccessLinear
 		owner	= _owner;
 	}
 	
+	public void
+	aboutToOpen()
+	
+		throws FMFileManagerException
+	{
+	}
+	
 	public long
 	getLength(
 		RandomAccessFile		raf )
@@ -93,6 +100,16 @@ FMFileAccessLinear
 	}
 	
 	public void
+	setPieceComplete(
+		RandomAccessFile	raf,
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws FMFileManagerException
+	{	
+	}
+	
+	public void
 	read(
 		RandomAccessFile	raf,
 		DirectByteBuffer	buffer,
@@ -134,7 +151,6 @@ FMFileAccessLinear
 	
 	public void
 	read(
-		FMFile				file,
 		RandomAccessFile	raf,
 		DirectByteBuffer[]	buffers,
 		long				offset )
@@ -253,13 +269,14 @@ FMFileAccessLinear
 			}
 			
 			throw( new FMFileManagerException( "read fails", e ));
+			
 		}finally{
 			
 			long elapsed_millis = ( SystemTime.getHighPrecisionCounter() - read_start )/1000000;
 
 			if ( elapsed_millis > 10*1000 ){
 				
-				System.out.println( "read took " + elapsed_millis + " for " + file.getName());
+				System.out.println( "read took " + elapsed_millis + " for " + owner.getString());
 			}
 		}
 	}
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessPieceReorderer.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessPieceReorderer.java
new file mode 100644
index 0000000..4f1a019
--- /dev/null
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessPieceReorderer.java
@@ -0,0 +1,832 @@
+/*
+ * Created on 28-Sep-2005
+ * Created by Paul Gardner
+ * Copyright (C) 2005, 2006 Aelitis, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * 
+ * AELITIS, SAS au capital de 46,603.30 euros
+ * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
+ *
+ */
+
+package com.aelitis.azureus.core.diskmanager.file.impl;
+
+import java.util.*;
+import java.io.*;
+import java.nio.ByteBuffer;
+
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentFile;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
+import org.gudy.azureus2.core3.util.DirectByteBufferPool;
+import org.gudy.azureus2.core3.util.FileUtil;
+import org.gudy.azureus2.core3.util.SystemTime;
+
+import com.aelitis.azureus.core.diskmanager.file.FMFileManagerException;
+
+public class 
+FMFileAccessPieceReorderer
+	implements FMFileAccess
+{
+/*
+ * Idea is to grow the file as needed on a piece-write basis
+ * 
+ * Each file in general starts with a part of a piece and then is optionally
+ * followed by zero or more complete pieces and ends with an option part of a piece.
+ * 
+ * The first part-piece of the file is always stored in position.
+ * 
+ * Whenever we receive a write request we calculate which piece number(s) it affects
+ * If we have already allocated piece sized chunks for the pieces then we simply write
+ * to the relevant part of the file
+ * If we haven't then we allocate new piece size chunks at file end and record their position in 
+ * the control file. If it now turns out that we have allocated the space required for a piece previously
+ * completed then we copy that piece data into the new block and reuse the space it has been
+ * copied from for the new chunk
+ * 
+ * When allocating space for the last part-piece we allocate an entire piece sized chunk and
+ * trim later
+ * 
+ * Whenever a piece is marked as complete we look up its location. If the required piece
+ * of the file has already been allocated (and its not alread in the right place) then
+ * we swap the piece data at that location with the current piece's. If the file chunk hasn't
+ * been allocated yet then we leave the piece where it is - it'll be moved later.
+ * 
+ * If the control file is lost then there is an opportunity to recover completed pieces by 
+ * hashing all of the allocated chunks and checking the SHA1 results with the file's piece hashes.
+ * However, this would require the addition of further interfaces etc to integrate somehow with
+ * the existing force-recheck functionality...
+ * 
+ * Obviously the setLength/getLength calls just have to be consistent, they don't actually
+ * modify the length of the physical file
+ * 
+ * Conversion between storage formats is another possibility to consider - conversion from this
+ * to linear can fairly easily be done here as it just needs pieces to be written to their 
+ * correct locations. Conversion to this format can't be done here as we don't know which
+ * pieces and blocks contain valid data. I guess such details could be added to the 
+ * setStorageType call as a further parameter
+ */
+	private static final boolean TRACE	= false;
+	
+	private static final int MIN_PIECES_REORDERABLE	= 3;	// first piece fixed at file start so need 3 to do anything worthwhile
+		
+	private static final byte SS_FILE = DirectByteBuffer.SS_FILE;
+	
+	private static final int	DIRT_CLEAN				= 0;
+	private static final int	DIRT_DIRTY				= 1;
+	private static final int	DIRT_NEVER_WRITTEN		= 2;
+	
+	private static final long	DIRT_FLUSH_MILLIS		= 30*1000;
+	
+	private FMFileAccess	delegate;
+	private File			control_dir;
+	private String			control_file;
+
+	
+	private int			piece_size;
+	
+	private int			first_piece_length;
+	private int			first_piece_number;
+	private int			last_piece_length;
+	
+	private int			num_pieces;
+		
+	private long	current_length;
+	private int[]	piece_map;
+	private int[]	piece_reverse_map;
+	private int		next_piece_index;
+	
+	private int		dirt_state;
+	private long	dirt_time		= -1;
+	
+	protected
+	FMFileAccessPieceReorderer(
+		TOTorrentFile	_torrent_file,
+		File			_control_dir,
+		String			_control_file,
+		FMFileAccess	_delegate )
+	
+		throws FMFileManagerException
+	{
+		delegate		= _delegate;
+		control_dir		= _control_dir;
+		control_file	= _control_file;
+	
+		try{
+			first_piece_number 	= _torrent_file.getFirstPieceNumber();
+
+			num_pieces = _torrent_file.getLastPieceNumber() - first_piece_number + 1;
+
+			if ( num_pieces >= MIN_PIECES_REORDERABLE ){
+
+				piece_size = (int)_torrent_file.getTorrent().getPieceLength();
+				
+				TOTorrent	torrent = _torrent_file.getTorrent();
+				
+				long	file_length	= _torrent_file.getLength();
+				
+				long	file_offset_in_torrent = 0;
+				
+				TOTorrentFile[] files = torrent.getFiles();
+				
+				for (int i=0;i<files.length;i++){
+					
+					TOTorrentFile	f = files[i];
+					
+					if ( f == _torrent_file ){
+						
+						break;
+					}
+					
+					file_offset_in_torrent	+= f.getLength();
+				}
+																
+				int first_piece_offset 	= (int)( file_offset_in_torrent % piece_size );
+
+				first_piece_length	= piece_size - first_piece_offset;
+			
+				long	file_end = file_offset_in_torrent + file_length;
+			
+			
+				last_piece_length = (int)( file_end - (( file_end / piece_size ) * piece_size ));
+				
+				if ( last_piece_length == 0 ){
+					
+					last_piece_length = piece_size;
+				}
+					
+			}
+			
+			dirt_state = new File( control_dir, control_file ).exists()?DIRT_CLEAN:DIRT_NEVER_WRITTEN;
+	
+		}catch( Throwable e ){
+				
+			throw( new FMFileManagerException( "Piece-reorder file init fail", e ));
+		}
+	}
+	
+	public void
+	aboutToOpen()
+	
+		throws FMFileManagerException
+	{				
+			// ensure control file exists as this marks the file as piece-reordered
+			// always do this, even for < MIN_PIECES_REORDERABLE piece files as
+			// we still need the control file to exist
+		
+		if ( dirt_state == DIRT_NEVER_WRITTEN ){
+				
+			writeConfig();
+		}
+	}
+	
+	public long
+	getLength(
+		RandomAccessFile		raf )
+	
+		throws FMFileManagerException
+	{
+		if ( num_pieces >= MIN_PIECES_REORDERABLE ){
+			
+			if ( piece_map == null ){
+				
+				readConfig();
+			}
+			
+			return( current_length );
+			
+		}else{
+			
+			return( delegate.getLength(raf));
+		}
+	}
+	
+	public void
+	setLength(
+		RandomAccessFile		raf,
+		long					length )
+	
+		throws FMFileManagerException
+	{
+		if ( num_pieces >= MIN_PIECES_REORDERABLE ){
+			
+			if ( piece_map == null ){
+				
+				readConfig();
+			}
+			
+			if ( current_length != length ){
+			
+				current_length = length;
+			
+				setDirty();
+			}
+		}else{
+			
+			delegate.setLength( raf, length );
+		}
+	}
+	
+	protected long
+	getPieceOffset(
+		RandomAccessFile	raf,
+		int					piece_number,
+		boolean				allocate_if_needed )
+	
+		throws FMFileManagerException
+	{
+		if ( piece_map == null ){
+			
+			readConfig();
+		}
+		
+		int index = getPieceIndex( raf, piece_number, allocate_if_needed );
+			
+		if ( index < 0 ){
+			
+			return( index );
+			
+		}else if ( index == 0 ){
+			
+			return( 0 );
+			
+		}else if ( index == 1 ){
+			
+			return( first_piece_length );
+			
+		}else{
+			
+			return( first_piece_length + ((index-1)*piece_size ));
+		}
+	}
+
+	protected int
+	readWritePiece(
+		RandomAccessFile		raf,
+		DirectByteBuffer[]		buffers,
+		int						piece_number,
+		int						piece_offset,
+		boolean					is_read )
+	
+		throws FMFileManagerException
+	{
+		String	str = is_read?"read":"write";
+			
+		if ( piece_number >= num_pieces ){
+			
+			throw( new FMFileManagerException( "Attempt to " + str + " piece " + piece_number + ": last=" + num_pieces ));
+		}
+		
+		int	this_piece_size = piece_number==0?first_piece_length:(piece_number==(num_pieces-1)?last_piece_length:piece_size);
+		
+		final int	piece_space = this_piece_size - piece_offset;
+		
+		if ( piece_space <= 0 ){
+			
+			throw( new FMFileManagerException( "Attempt to " + str + " piece " + piece_number + ", offset " + piece_offset + " - no space in piece" ));
+		}
+		
+		int	rem_space = piece_space;
+		
+		int[]	limits = new int[buffers.length];
+	
+		for ( int i=0;i<buffers.length;i++ ){
+			
+			DirectByteBuffer buffer = buffers[i];
+			
+			limits[i] = buffer.limit( SS_FILE );
+			
+			int	rem = buffer.remaining( SS_FILE );
+
+			if ( rem > rem_space ){
+				
+				buffer.limit( SS_FILE, buffer.position( SS_FILE ) + rem_space );
+				
+				rem_space = 0;
+				
+			}else{
+				
+				rem_space -= rem;
+			}
+		}
+		
+		try{
+
+			long piece_start = getPieceOffset( raf, piece_number, !is_read );
+			 
+			if ( TRACE ){
+				System.out.println( str + " to " + piece_number + "/" + piece_offset + "/" + this_piece_size + "/" + piece_space + "/" + rem_space + "/" + piece_start );
+			}
+
+			if ( piece_start == -1 ){
+				
+				return( 0 );
+			}
+			
+			long piece_io_position = piece_start + piece_offset;
+				
+			if ( is_read ){
+			
+				delegate.read( raf, buffers, piece_io_position );
+				
+			}else{
+				
+				delegate.write( raf, buffers, piece_io_position );
+			}
+			
+			return( piece_space - rem_space );
+			
+		}finally{
+			
+			for ( int i=0;i<buffers.length;i++ ){
+
+				buffers[i].limit( SS_FILE, limits[i] );
+			}
+		}
+	}
+	
+	protected void
+	readWrite(
+		RandomAccessFile		raf,
+		DirectByteBuffer[]		buffers,
+		long					position,
+		boolean					is_read )
+	
+		throws FMFileManagerException
+	{		
+		long	total_length = 0;
+		
+		for ( DirectByteBuffer buffer: buffers ){
+			
+			total_length += buffer.remaining( SS_FILE );
+		}
+		
+		if ( !is_read && position + total_length > current_length ){
+			
+			current_length = position + total_length;
+			
+			setDirty();
+		}
+		
+		long	current_position = position;
+		
+		while( total_length > 0 ){		
+			
+			int	piece_number;
+			int	piece_offset;
+
+			if ( current_position < first_piece_length ){
+				
+				piece_number 	= 0;
+				piece_offset	= (int)current_position;
+				
+			}else{
+				
+				long	offset = current_position - first_piece_length;
+				
+				piece_number 	= (int)( offset / piece_size ) + 1;
+			
+				piece_offset	= (int)( offset % piece_size );
+			}
+			
+			int	count = readWritePiece( raf, buffers, piece_number, piece_offset, is_read );
+			
+			if ( count == 0 ){
+				
+				if ( is_read ){
+					
+						// fill remaining space with zeros so we're consistent
+					
+					for ( DirectByteBuffer buffer: buffers ){
+
+						ByteBuffer bb = buffer.getBuffer( SS_FILE );
+						
+						int	rem = bb.remaining();
+						
+						bb.put( new byte[rem] );
+					}
+				}else{
+				
+					throw( new FMFileManagerException( "partial write operation" ));
+				}
+				
+				return;
+			}
+			
+			total_length 		-= count;
+			current_position 	+= count;
+		}
+	}
+	
+	public void
+	read(
+		RandomAccessFile		raf,
+		DirectByteBuffer[]		buffers,
+		long					position )
+	
+		throws FMFileManagerException
+	{		
+		if ( num_pieces >= MIN_PIECES_REORDERABLE ){
+
+			readWrite( raf, buffers, position, true );
+			
+		}else{
+			
+			delegate.read( raf, buffers, position );
+		}
+	}
+		
+	public void
+	write(
+		RandomAccessFile		raf,
+		DirectByteBuffer[]		buffers,
+		long					position )
+	
+		throws FMFileManagerException
+	{	
+		if ( num_pieces >= MIN_PIECES_REORDERABLE ){
+
+			readWrite( raf, buffers, position, false );
+			
+		}else{
+			
+			delegate.write( raf, buffers, position );
+		}
+	}
+	
+	public void
+	flush()
+	
+		throws FMFileManagerException
+	{
+		if ( num_pieces >= MIN_PIECES_REORDERABLE ){
+		
+			if ( dirt_state != DIRT_CLEAN ){
+			
+				writeConfig();
+			}
+		}else{
+			
+			delegate.flush();
+		}
+	}
+	
+	public void
+	setPieceComplete(
+		RandomAccessFile	raf,
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws FMFileManagerException
+	{	
+		if ( num_pieces >= MIN_PIECES_REORDERABLE ){
+				
+				// note that it is possible to reduce the number of piece moves at the expense
+				// of complicating the allocation process. We have the advantage here of having
+				// the piece data already in memory. We also don't want to defer a mass of IO
+				// until the download completes, hence interfering with other stuff such as
+				// streaming. So I'm going to stick with this approach.
+			
+			piece_number = piece_number - first_piece_number;
+			
+			if ( TRACE ){
+				System.out.println( "pieceComplete: " + piece_number );
+			}
+
+			if ( piece_number >= next_piece_index ){
+			
+					// nothing stored yet in the location where this piece belongs
+				
+				return;
+			}
+			
+			int	store_index = getPieceIndex( raf, piece_number, false );
+			
+			if ( store_index == -1 ){
+				
+				throw( new FMFileManagerException( "piece marked as complete but not yet allocated" ));
+			}
+			
+			if ( piece_number == store_index ){
+				
+					// already in the right place
+				
+				if ( TRACE ){
+					System.out.println( "    already in right place" );
+				}
+				
+				return;
+			}
+			
+				// find out what's currently stored in the place this piece should be 
+			
+			int	swap_piece_number = piece_reverse_map[ piece_number ];
+			
+			if ( swap_piece_number < 1 ){
+				
+				throw( new FMFileManagerException( "Inconsistent: failed to find piece to swap" ));
+			}
+			
+			if ( TRACE ){
+				System.out.println( "    swapping " + piece_number + " and " + swap_piece_number + ": " + piece_number + " <-> " + store_index );
+			}
+			
+			DirectByteBuffer temp_buffer = DirectByteBufferPool.getBuffer( SS_FILE, piece_size );
+			
+			DirectByteBuffer[] temp_buffers = new DirectByteBuffer[]{ temp_buffer };
+			
+			try{
+				long	store_offset = first_piece_length + ((store_index-1)*piece_size );
+				long	swap_offset	 = first_piece_length + ((piece_number-1)*piece_size );
+				
+				delegate.read( raf, temp_buffers, swap_offset );
+				
+				piece_data.position( SS_FILE, 0 );
+				
+				delegate.write( raf, new DirectByteBuffer[]{ piece_data }, swap_offset );
+				
+				temp_buffer.position( SS_FILE, 0 );
+				
+				delegate.write( raf, temp_buffers, store_offset );
+				
+				piece_map[ piece_number ] 			= piece_number;
+				piece_reverse_map[ piece_number ] 	= piece_number;
+				
+				piece_map[ swap_piece_number ] 		= store_index;
+				piece_reverse_map[ store_index ] 	= swap_piece_number;
+				
+				setDirty();
+				
+				if ( piece_number == num_pieces - 1 ){
+					
+					long	file_length = swap_offset + last_piece_length;
+					
+					if ( delegate.getLength( raf ) > file_length ){
+						
+						if ( TRACE ){
+							System.out.println( "    truncating file to correct length of " + file_length );
+						}
+						
+						delegate.setLength( raf, file_length );
+					}
+				}
+			}finally{
+				
+				temp_buffer.returnToPool();
+			}
+		}else{
+			
+			delegate.setPieceComplete( raf, piece_number, piece_data );
+		}
+	}
+
+	protected int
+	getPieceIndex(
+		RandomAccessFile	raf,
+		int					piece_number,
+		boolean				allocate_if_needed )
+	
+		throws FMFileManagerException
+	{		
+		int	store_index = piece_map[ piece_number ];
+				
+		if ( store_index == -1 && allocate_if_needed ){
+			
+			store_index = next_piece_index++;
+			
+			if ( TRACE ){
+				System.out.println( "getPiece(" + piece_number + "): allocated " + store_index );
+			}
+			
+			piece_map[ piece_number ] = store_index;
+			piece_reverse_map[ store_index ] = piece_number;
+			
+			if ( piece_number != store_index ){
+				
+					// not already in the right place, see if the piece we just allocated
+					// corresponds to a piece previously allocated and swap if so
+				
+				int	swap_index = piece_map[ store_index ];
+								
+				if ( swap_index > 0 ){
+					
+					if ( TRACE ){
+						System.out.println( "    piece number " + store_index + " already allocated at " + swap_index + ": moving piece ");
+					}
+												
+					DirectByteBuffer temp_buffer = DirectByteBufferPool.getBuffer( SS_FILE, piece_size );
+					
+					DirectByteBuffer[] temp_buffers = new DirectByteBuffer[]{ temp_buffer };
+	
+					try{
+						long	store_offset 	= first_piece_length + ((store_index-1)*piece_size );
+						long	swap_offset 	= first_piece_length + ((swap_index-1)*piece_size );
+
+						delegate.read( raf, temp_buffers, swap_offset );
+
+						temp_buffer.position( SS_FILE, 0 );
+						
+						delegate.write( raf, temp_buffers, store_offset );
+
+						piece_map[ store_index ] 			= store_index;
+						piece_reverse_map[ store_index ] 	= store_index;
+						
+						piece_map[ piece_number ]		= swap_index;
+						piece_reverse_map[ swap_index ]	= piece_number;
+											
+						if ( store_index == num_pieces - 1 ){
+							
+							long	file_length = store_offset + last_piece_length;
+							
+							if ( delegate.getLength( raf ) > file_length ){
+								
+								if ( TRACE ){
+									System.out.println( "    truncating file to correct length of " + file_length );
+								}
+								
+								delegate.setLength( raf, file_length );
+							}
+						}
+						
+						store_index = swap_index;
+
+					}finally{
+						
+						temp_buffer.returnToPool();
+					}
+				}
+			}
+			
+			setDirty();
+		}
+		
+		// System.out.println( "getPiece: " + piece_number + "->" + store_index );
+		
+		return( store_index );
+	}
+	
+	protected void
+	readConfig()
+	
+		throws FMFileManagerException
+	{
+		piece_map 			= new int[num_pieces];
+		piece_reverse_map 	= new int[num_pieces];
+
+		if ( dirt_state == DIRT_NEVER_WRITTEN ){
+					
+			Arrays.fill( piece_map, -1 );
+			
+			piece_map[0]			= 0;
+			piece_reverse_map[0]	= 0;
+			next_piece_index 		= 1;
+			current_length			= 0;
+			
+		}else{
+			
+			Map map = FileUtil.readResilientFile( control_dir, control_file, false );
+			
+			Long	l_len		= (Long)map.get( "len" );
+			Long	l_next		= (Long)map.get( "next" );
+			byte[]	piece_bytes = (byte[])map.get( "pieces" );
+			
+			if ( l_len == null || l_next == null || piece_bytes == null ){
+			
+				throw( new FMFileManagerException( "Failed to read control file " + new File( control_dir, control_file ).getAbsolutePath() + ": map invalid - " + map ));
+			}
+			
+			current_length 		= l_len.longValue();
+			next_piece_index	= l_next.intValue();
+			
+			if ( piece_bytes.length != num_pieces * 4 ){
+				
+				throw( new FMFileManagerException( "Failed to read control file " + new File( control_dir, control_file ).getAbsolutePath() + ": piece bytes invalid" ));
+			}
+			
+			int	pos = 0;
+			
+			for (int i=0;i<num_pieces;i++){
+			
+				int	index = 
+					( piece_bytes[pos++] << 24 ) + 
+					(( piece_bytes[pos++] & 0xff ) << 16 ) +
+					(( piece_bytes[pos++] & 0xff ) << 8 ) +
+					(( piece_bytes[pos++] & 0xff ));
+				
+				piece_map[i] = index;
+
+				if ( index != -1 ){
+				
+					piece_reverse_map[ index ] = i;
+				}
+			}
+		}
+		
+		if ( TRACE ){
+			System.out.println( "ReadConfig: length=" + current_length + ", next=" + next_piece_index );
+		}
+	}
+
+	protected void
+	setDirty()
+	
+		throws FMFileManagerException
+	{
+		if ( dirt_state == DIRT_NEVER_WRITTEN ){
+			
+			Debug.out( "shouldn't get here" );
+			
+			writeConfig();
+				
+		}else{
+			long	now = SystemTime.getMonotonousTime();
+			
+			if ( dirt_state == DIRT_CLEAN ){
+			
+				dirt_state 	= DIRT_DIRTY;
+				dirt_time	= now;
+				
+			}else{
+				
+				if ( dirt_time >= 0 && ( now - dirt_time >= DIRT_FLUSH_MILLIS )){
+					
+					writeConfig();
+				}
+			}
+		}
+	}
+
+	protected void
+	writeConfig()
+	
+		throws FMFileManagerException
+	{
+		if ( piece_map == null ){
+			
+			readConfig();
+		}
+		
+		Map	map = new HashMap();
+		
+		map.put( "len", 	new Long( current_length ));
+		map.put( "next", 	new Long( next_piece_index ));
+		
+		byte[]	pieces_bytes = new byte[ piece_map.length * 4 ];
+		
+		int	pos = 0;
+		
+		for (int i=0;i<piece_map.length;i++){
+		
+			int	value = piece_map[i];
+			
+			if ( value == -1 ){
+				
+				pieces_bytes[pos++] = pieces_bytes[pos++] = pieces_bytes[pos++] = pieces_bytes[pos++] = (byte)0xff;
+				
+			}else{
+				
+				pieces_bytes[pos++] = (byte)( value >> 24 );
+				pieces_bytes[pos++] = (byte)( value >> 16 );
+				pieces_bytes[pos++] = (byte)( value >> 8 );
+				pieces_bytes[pos++] = (byte)( value );
+			}
+		}
+		
+		map.put( "pieces", 	pieces_bytes );
+		
+		if ( !control_dir.exists()){
+			
+			control_dir.mkdirs();
+		}
+		
+		if ( !FileUtil.writeResilientFileWithResult( control_dir, control_file, map )){
+			
+			throw( new FMFileManagerException( "Failed to write control file " + new File( control_dir, control_file ).getAbsolutePath()));
+		}
+
+		if ( TRACE ){
+			System.out.println( "WriteConfig: length=" + current_length + ", next=" + next_piece_index );
+		}
+		
+		dirt_state 	= DIRT_CLEAN;
+		dirt_time	= -1;
+	}
+	
+	public String
+	getString()
+	{
+		return( "reorderer" );
+	}
+}
\ No newline at end of file
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileImpl.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileImpl.java
index b13d2f0..01aa28d 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileImpl.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileImpl.java
@@ -43,14 +43,14 @@ FMFileImpl
 	implements FMFile
 {	
 	protected static final String		READ_ACCESS_MODE	= "r";
-	protected static final String		WRITE_ACCESS_MODE	= "rwd";
+	protected static final String		WRITE_ACCESS_MODE	= "rw"; // "rwd"; - removing this to improve performance
 	
 	private static Map			file_map = new HashMap();
 	private static AEMonitor	file_map_mon	= new AEMonitor( "FMFile:map");
 	
 	// If there is an exception that occurs, which causes us to try and perform
 	// a reopen, setting this flag to true will print it to debug.
-	private static boolean OUTPUT_REOPEN_RELATED_ERRORS = false; 
+	private static boolean OUTPUT_REOPEN_RELATED_ERRORS = true; 
 	
 	static{
 		AEDiagnostics.addEvidenceGenerator(
@@ -545,6 +545,8 @@ FMFileImpl
 				// if the subsequent open fails
 		}
 		
+		file_access.aboutToOpen();
+		
 		raf = new RandomAccessFile( linked_file, access_mode==FM_READ?READ_ACCESS_MODE:WRITE_ACCESS_MODE);
 		
 		Debug.outNoStack( "Recovered connection to " + getName() + " after access failure" );
@@ -563,7 +565,9 @@ FMFileImpl
 
 		reserveAccess( reason );
 		
-		try{		
+		try{	
+			file_access.aboutToOpen();
+			
 			raf = new RandomAccessFile( linked_file, access_mode==FM_READ?READ_ACCESS_MODE:WRITE_ACCESS_MODE);
 			
 		}catch( Throwable e ){
@@ -634,6 +638,16 @@ FMFileImpl
 		file_access.flush();
 	}
 	
+	protected void
+	setPieceCompleteSupport(
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws FMFileManagerException
+	{
+		file_access.setPieceComplete( raf, piece_number, piece_data );
+	}
+	
 	public void
 	delete()
 	
@@ -669,7 +683,7 @@ FMFileImpl
 	{
 		try{
 		
-			file_access.read( this, raf, buffers, position );
+			file_access.read( raf, buffers, position );
 			
 		}catch( FMFileManagerException e ){
 			
@@ -678,7 +692,7 @@ FMFileImpl
 			try{
 				reopen();
 
-				file_access.read( this, raf, buffers, position );
+				file_access.read( raf, buffers, position );
 				
 			}catch( Throwable e2 ){
 				
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileLimited.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileLimited.java
index 1c398e5..54014e6 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileLimited.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileLimited.java
@@ -179,6 +179,26 @@ FMFileLimited
 	}
 	
 	public void
+	setPieceComplete(
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws FMFileManagerException
+	{
+		try{
+			this_mon.enter();
+		
+			ensureOpen( "FMFileLimited:setPieceComplete" );
+			
+			setPieceCompleteSupport( piece_number, piece_data );
+			
+		}finally{
+			
+			this_mon.exit();
+		}	
+	}
+	
+	public void
 	read(
 		DirectByteBuffer[]	buffers,
 		long				offset )
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileUnlimited.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileUnlimited.java
index 62f7952..d3a411f 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileUnlimited.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileUnlimited.java
@@ -132,9 +132,29 @@ FMFileUnlimited
 	}
 	
 	public void
+	setPieceComplete(
+		int					piece_number,
+		DirectByteBuffer	piece_data )
+	
+		throws FMFileManagerException
+	{
+		try{
+			this_mon.enter();
+		
+			ensureOpen( "FMFileUnlimited:setPieceComplete" );
+			
+			setPieceCompleteSupport( piece_number, piece_data );
+			
+		}finally{
+			
+			this_mon.exit();
+		}	
+	}
+	
+	public void
 	read(
 		DirectByteBuffer	buffer,
-		long		offset )
+		long				offset )
 	
 		throws FMFileManagerException
 	{
diff --git a/com/aelitis/azureus/core/download/DownloadManagerEnhancer.java b/com/aelitis/azureus/core/download/DownloadManagerEnhancer.java
index 0adcf34..4d10fb0 100644
--- a/com/aelitis/azureus/core/download/DownloadManagerEnhancer.java
+++ b/com/aelitis/azureus/core/download/DownloadManagerEnhancer.java
@@ -33,7 +33,6 @@ import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 import org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerChannelImpl;
 
 import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.torrent.MetaDataUpdateListener;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.util.ExternalStimulusHandler;
 import com.aelitis.azureus.util.ExternalStimulusListener;
@@ -45,8 +44,6 @@ public class
 DownloadManagerEnhancer 
 {
 	public static final int	TICK_PERIOD				= 1000;
-	public static final int	PUBLISHING_CHECK_PERIOD	= 15000;
-	public static final int	PUBLISHING_CHECK_TICKS	= PUBLISHING_CHECK_PERIOD / TICK_PERIOD;
 	
 	private static DownloadManagerEnhancer		singleton;
 	
@@ -127,31 +124,6 @@ DownloadManagerEnhancer
 			    }
 			});
 		
-		PlatformTorrentUtils.addListener(
-			new MetaDataUpdateListener()
-			{
-				public void 
-				metaDataUpdated(
-					TOTorrent torrent )
-				{
-					 DownloadManager dm = core.getGlobalManager().getDownloadManager( torrent );
-
-					 if ( dm == null ){
-						 
-						 Debug.out( "Meta data update: download not found for " + torrent );
-						 
-					 }else{
-						
-						 EnhancedDownloadManager edm = getEnhancedDownload( dm );
-						 
-						 if ( edm != null ){
-							 
-							 edm.refreshMetaData();
-						 }
-					 }
-				}
-			});
-		
 		ExternalStimulusHandler.addListener(
 			new ExternalStimulusListener()
 			{
@@ -270,8 +242,6 @@ DownloadManagerEnhancer
 					{
 						tick_count++;
 						
-						boolean	check_publish = tick_count % PUBLISHING_CHECK_TICKS == 0;
-						
 						List	downloads = core.getGlobalManager().getDownloadManagers();
 						
 						for ( int i=0;i<downloads.size();i++){
@@ -290,11 +260,6 @@ DownloadManagerEnhancer
 								
 								edm.updateStats( tick_count );
 							
-								if ( 	state == DownloadManager.STATE_SEEDING &&
-										check_publish ){
-											
-									edm.checkPublishing();
-								}
 							}
 						}
 					}
diff --git a/com/aelitis/azureus/core/download/EnhancedDownloadManager.java b/com/aelitis/azureus/core/download/EnhancedDownloadManager.java
index 5d9eb15..b044f68 100644
--- a/com/aelitis/azureus/core/download/EnhancedDownloadManager.java
+++ b/com/aelitis/azureus/core/download/EnhancedDownloadManager.java
@@ -37,26 +37,9 @@ import org.gudy.azureus2.core3.download.DownloadManagerListener;
 import org.gudy.azureus2.core3.download.DownloadManagerPeerListener;
 import org.gudy.azureus2.core3.download.impl.DownloadManagerAdapter;
 import org.gudy.azureus2.core3.global.GlobalManager;
-import org.gudy.azureus2.core3.peer.PEPeer;
-import org.gudy.azureus2.core3.peer.PEPeerManager;
-import org.gudy.azureus2.core3.peer.PEPeerManagerStats;
-import org.gudy.azureus2.core3.peer.PEPeerStats;
-import org.gudy.azureus2.core3.peer.PEPiece;
+import org.gudy.azureus2.core3.peer.*;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
-import org.gudy.azureus2.core3.util.AEDiagnostics;
-import org.gudy.azureus2.core3.util.AEDiagnosticsLogger;
-import org.gudy.azureus2.core3.util.AESemaphore;
-import org.gudy.azureus2.core3.util.AEThread2;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.DisplayFormatters;
-import org.gudy.azureus2.core3.util.RealTimeInfo;
-import org.gudy.azureus2.core3.util.SystemTime;
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.peers.PeerManager;
-import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
-import org.gudy.azureus2.pluginsimpl.local.utils.PooledByteBufferImpl;
+import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.peer.cache.CacheDiscovery;
 import com.aelitis.azureus.core.peer.cache.CachePeer;
@@ -71,7 +54,13 @@ import com.aelitis.azureus.plugins.extseed.ExternalSeedManualPeer;
 import com.aelitis.azureus.plugins.extseed.ExternalSeedPlugin;
 import com.aelitis.azureus.util.ConstantsVuze;
 import com.aelitis.azureus.util.DownloadUtils;
-import com.aelitis.azureus.util.PublishUtils;
+
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.peers.PeerManager;
+
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.pluginsimpl.local.utils.PooledByteBufferImpl;
 
 public class 
 EnhancedDownloadManager 
@@ -1082,8 +1071,7 @@ EnhancedDownloadManager
 						continue;
 					}
 
-					if (!dmCheck.isDownloadComplete(false)
-							&& PlatformTorrentUtils.getAdId(dmCheck.getTorrent()) == null) {
+					if (!dmCheck.isDownloadComplete(false)) {
 						int state = dmCheck.getState();
 						if (state == DownloadManager.STATE_DOWNLOADING
 								|| state == DownloadManager.STATE_QUEUED) {
@@ -1281,100 +1269,7 @@ EnhancedDownloadManager
 			}
 		}
 	}
-	
-	protected void
-	checkPublishing()
-	{
-		if ( publish_handling_complete ){
-			
-			return;
-		}
-		
-		if ( PublishUtils.isPublished( download_manager )){
-			
-			if ( PublishUtils.isPublishComplete( download_manager )){
-				
-				publish_handling_complete = true;
-				
-			}else{
-				
-				TRTrackerScraperResponse scrape = download_manager.getTrackerScrapeResponse();
-				
-				if ( scrape == null || scrape.getStatus() != TRTrackerScraperResponse.ST_ONLINE ){
-					
-					return;
-				}
-				
-				if ( scrape.getSeeds() >= 2 ){
-									
-					PublishUtils.setPublishComplete( download_manager );
-					
-					publish_handling_complete = true;
-					
-				}else{
-					
-					PEPeerManager pm = download_manager.getPeerManager();
-				
-					if ( pm != null ){
-				
-						long	now = SystemTime.getCurrentTime();
-						
-						long	pub_sent = download_manager.getStats().getTotalDataBytesSent();
-						
-						if ( pub_sent != publish_sent ){
-							
-							publish_sent = pub_sent;
-						
-							publish_sent_time = now;
-						}
-						
-						if ( publish_sent_time > now ){
-							
-							publish_sent_time = now;
-						}
-						
-						if ( now - publish_sent_time > STALLED_TIMEOUT ){
-							
-							publish_sent_time = now;
-							
-							log( "Publish: upload stalled - switching transports" );
-							
-								// no data uploded recently. 
-							
-							pm.setPreferUDP( !pm.getPreferUDP());
-							
-							List peers = pm.getPeers();
-							
-							for (int i=0;i<peers.size();i++){
-								
-								PEPeer peer = (PEPeer)peers.get(i);
-								
-								pm.removePeer( peer, "Transport switch" );
-							}
-							
-							download_manager.requestTrackerAnnounce( true );					
 
-						}else if ( pm.getNbPeers() == 0 ){
-									
-							log( "Publish: no connected peers, forcing announce" );
-							
-							download_manager.requestTrackerAnnounce( true );					
-						}
-					}
-				}
-			}		
-		}else{
-			
-				// we've only got to handle the possible small delay here between a download being
-				// added and the flag being set
-			
-			if ( SystemTime.getCurrentTime() - time_download_started > 120*1000 ){
-				
-				publish_handling_complete = true;
-			}
-		}
-	}
-	
 	public DiskManagerFileInfo
 	getPrimaryFile()
 	{
diff --git a/com/aelitis/azureus/core/drm/msdrm/CheckVersionRequiredException.java b/com/aelitis/azureus/core/drm/msdrm/CheckVersionRequiredException.java
deleted file mode 100644
index 8de9474..0000000
--- a/com/aelitis/azureus/core/drm/msdrm/CheckVersionRequiredException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.aelitis.azureus.core.drm.msdrm;
-
-public class CheckVersionRequiredException extends Exception {
-	
-	public CheckVersionRequiredException(String message) {
-		super(message);
-	}
-
-}
diff --git a/com/aelitis/azureus/core/drm/msdrm/DRMUpdateRequiredException.java b/com/aelitis/azureus/core/drm/msdrm/DRMUpdateRequiredException.java
deleted file mode 100644
index c5b642e..0000000
--- a/com/aelitis/azureus/core/drm/msdrm/DRMUpdateRequiredException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.aelitis.azureus.core.drm.msdrm;
-
-public class DRMUpdateRequiredException extends Exception {
-	
-	public DRMUpdateRequiredException(String message) {
-		super(message);
-	}
-
-}
diff --git a/com/aelitis/azureus/core/drm/msdrm/ExceededDRMDeliveryLimitException.java b/com/aelitis/azureus/core/drm/msdrm/ExceededDRMDeliveryLimitException.java
deleted file mode 100644
index 51eee87..0000000
--- a/com/aelitis/azureus/core/drm/msdrm/ExceededDRMDeliveryLimitException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.aelitis.azureus.core.drm.msdrm;
-
-public class ExceededDRMDeliveryLimitException extends Exception {
-	
-	public ExceededDRMDeliveryLimitException(String message) {
-		super(message);
-	}
-
-}
diff --git a/com/aelitis/azureus/core/drm/msdrm/LicenseAquirer.java b/com/aelitis/azureus/core/drm/msdrm/LicenseAquirer.java
deleted file mode 100644
index 544761f..0000000
--- a/com/aelitis/azureus/core/drm/msdrm/LicenseAquirer.java
+++ /dev/null
@@ -1,335 +0,0 @@
-package com.aelitis.azureus.core.drm.msdrm;
-
-import java.util.Map;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.browser.StatusTextEvent;
-import org.eclipse.swt.browser.StatusTextListener;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.gudy.azureus2.core3.util.AESemaphore;
-import org.json.simple.JSONObject;
-
-import com.aelitis.azureus.core.messenger.PlatformMessage;
-import com.aelitis.azureus.core.messenger.PlatformMessenger;
-import com.aelitis.azureus.core.messenger.PlatformMessengerListener;
-import com.aelitis.azureus.login.NotLoggedInException;
-
-public class LicenseAquirer {
-	
-	//private static final String PROGID = "DRM.GetLicense";
-	
-	private static final String STATUS_REQUESTED = "requested";
-	private static final String STATUS_INSTALLED = "installed";
-	private static final String STATUS_SUCCESS = "success";
-	private static final String STATUS_UPDATE = "update";
-	private static final String STATUS_FAILURE = "failure";
-	private static final String STATUS_CLIENT_FAILURE = "client-failure";
-
-	private static final String ERROR_INCOMPATIBLE_CLIENT = "Incompatible Client";
-	private static final String ERROR_SERVER_COMMUNICATION= "Server did not send a valid response";
-	private static final String ERROR_EXCEEDED_DRM_DELIVERY_LIMIT = "Key delivery limit exceeded.";
-	
-	private Browser browser;
-	
-	public LicenseAquirer(Composite composite) {
-		browser = new Browser(composite,SWT.NONE);
-		browser.setText("<html><body><object id=\"netobj\" classid=\"clsid:A9FC132B-096D-460B-B7D5-1DB0FAE0C062\" width=\"0\" height=\"0\"></object></body></html>");
-		browser.setVisible(false);
-	}
-	
-	private String getSystemInfo() throws LicenseAquisitionException {
-		final AESemaphore sem = new AESemaphore("waitForBrowserResponse");
-		final String[] result  = {null};
-		
-		browser.getDisplay().asyncExec(new Runnable() {
-			public void run() {
-				browser.addStatusTextListener(new StatusTextListener() {
-					public void changed(StatusTextEvent event) {
-						if( ! ("".equals(event.text) ) ) {
-							browser.removeStatusTextListener(this);
-							result[0] = event.text;
-							sem.release();
-						}
-					}
-				});
-				
-				browser.execute("try {window.status = netobj.GetSystemInfo(); } catch(e) { window.status= 'ERROR : ' + e ; }");
-			}
-		});
-		
-		sem.reserve(10000);
-		
-		if(result[0] == null) {
-			throw new LicenseAquisitionException("JS Call did not complete");
-		}
-		
-		if(result[0].startsWith("ERROR : ")) {
-			throw new LicenseAquisitionException("JS Call returned : " + result[0]);
-		}
-
-		return result[0];
-		
-	}
-	
-	private String getDRMVersion() throws LicenseAquisitionException {
-		
-		final AESemaphore sem = new AESemaphore("waitForBrowserResponse");
-		final String[] result  = {null};
-		
-		browser.getDisplay().asyncExec(new Runnable() {
-			public void run() {
-				browser.addStatusTextListener(new StatusTextListener() {
-					public void changed(StatusTextEvent event) {
-						browser.removeStatusTextListener(this);
-						result[0] = event.text;
-						sem.release();
-					}
-				});
-				
-				browser.execute("try { window.status = netobj.GetDRMVersion(); } catch(e) { window.status= 'ERROR : ' + e ; }");
-			}
-		});
-		
-		sem.reserve(10000);
-		
-		if(result[0] == null) {
-			throw new LicenseAquisitionException("JS Call did not complete");
-		}
-		
-		if(result[0].startsWith("ERROR : ")) {
-			throw new LicenseAquisitionException("JS Call returned : " + result[0]);
-		}
-		
-		return result[0];
-		
-	}
-	
-	private void storeLicense(final String license) throws LicenseAquisitionException {
-		browser.getDisplay().asyncExec(new Runnable() {
-			public void run() {
-					browser.execute("netobj.StoreLicense(" + license + ");");	
-			}
-		});
-	}
-	
-	private void makeRPCRequest(String rpcCommand, JSONObject rpcParameters, PlatformMessengerListener listener) throws LicenseAquisitionException {
-		PlatformMessage message = new PlatformMessage("drm", "drm", rpcCommand,rpcParameters,60*1000);
-		PlatformMessenger.queueMessage(message, listener);
-	}
-	
-	private boolean checkDRMVersion(String systemInfo,String drmVersion) throws LicenseAquisitionException,DRMUpdateRequiredException {
-		JSONObject parameters = new JSONObject();
-		parameters.put("drmVersion", drmVersion);
-		parameters.put("clientInfo", systemInfo);
-		
-		final AESemaphore sem = new AESemaphore( "waitForPlatformResponse" );
-		
-		final Boolean[] result = {null};
-		final Exception[] error = {null};
-		
-		makeRPCRequest("check", parameters,new PlatformMessengerListener() {
-			public void messageSent(PlatformMessage message) {
-				
-			}
-			
-			public void replyReceived(PlatformMessage message,
-					String replyType, Map reply) {
-				try {
-					if("response".equals(replyType)) {
-	
-						if(reply.get("action") != null) {
-							Map action = (Map) reply.get("action");
-							if(action.get("name") != null) {
-								String name = (String) action.get("name");
-								if("update".equals(name)) {
-									error[0] = new DRMUpdateRequiredException((String) action.get("url"));
-								}
-								if("success".equals(name)) {
-									result[0] = new Boolean(true);
-								}
-							}
-							
-							error[0] = new LicenseAquisitionException("no action, or invalid action in response");
-							return;
-						}
-						
-					}
-					if("exception".equals(replyType)) {
-						error[0] = new LicenseAquisitionException("Platform Call returned : " + reply.toString() ); 
-					}
-				} finally {
-					sem.release();
-				}
-				
-				
-			}
-		});
-		
-		sem.reserve();
-		
-		if(result[0] == null && error[0] == null) {
-			throw new LicenseAquisitionException("Platform Call did not complete");
-		}
-		
-		if(error[0] != null) {
-			if(error[0] instanceof LicenseAquisitionException) {
-				throw (LicenseAquisitionException) error[0];
-			}
-			
-			if(error[0] instanceof DRMUpdateRequiredException) {
-				throw (DRMUpdateRequiredException) error[0];
-			}
-			
-			throw new LicenseAquisitionException(error[0].getMessage());
-		}
-		
-		Boolean res = result[0];
-		
-		if(res != null) {
-			return res.booleanValue();
-		}
-		
-		return false;
-
-	}
-	
-	private String getLicenseFromPlatform(String systemInfo,String contentHash) throws LicenseAquisitionException,CheckVersionRequiredException,ExceededDRMDeliveryLimitException {
-		JSONObject parameters = new JSONObject();
-		parameters.put("hash", contentHash);
-		parameters.put("clientInfo", systemInfo);
-		
-		final AESemaphore sem = new AESemaphore( "waitForPlatformResponse" );
-		
-		final String[] result = {null};
-		final Exception[] error = {null};
-		
-		makeRPCRequest("deliver", parameters,new PlatformMessengerListener() {
-			public void messageSent(PlatformMessage message) {
-				System.out.println("sent");
-				
-			}
-			
-			public void replyReceived(PlatformMessage message,
-					String replyType, Map reply) {
-				try {
-					if("response".equals(replyType)) {
-						
-						
-						if(reply.get("license") != null) {
-							result[0] = (String) reply.get("license");
-							return;
-						}
-						
-						if(reply.get("rejected") != null && ERROR_EXCEEDED_DRM_DELIVERY_LIMIT.equals(reply.get("rejected"))) {
-							error[0] = new ExceededDRMDeliveryLimitException(ERROR_EXCEEDED_DRM_DELIVERY_LIMIT);
-							return;
-						}
-						
-						if(reply.get("action") != null) {
-							Map action = (Map) reply.get("action");
-							if(action.get("name") != null) {
-								String name = (String) action.get("name");
-								if("check".equals(name)) {
-									error[0] = new CheckVersionRequiredException(ERROR_EXCEEDED_DRM_DELIVERY_LIMIT);
-								}
-							}
-							
-							error[0] = new LicenseAquisitionException("no action, or invalid action in response");
-							return;
-						}
-						
-					}
-					if("exception".equals(replyType)) {
-						error[0] = new LicenseAquisitionException("Platform Call returned : " + reply.toString() ); 
-					}
-				} finally {
-					sem.release();
-				}
-				
-				
-			}
-		});
-		
-		sem.reserve();
-		
-		if(result[0] == null && error[0] == null) {
-			throw new LicenseAquisitionException("Platform Call did not complete");
-		}
-		
-		if(error[0] != null) {
-			if(error[0] instanceof LicenseAquisitionException) {
-				throw (LicenseAquisitionException) error[0];
-			}
-			
-			if(error[0] instanceof CheckVersionRequiredException) {
-				throw (CheckVersionRequiredException) error[0];
-			}
-			
-			if(error[0] instanceof ExceededDRMDeliveryLimitException) {
-				throw (ExceededDRMDeliveryLimitException) error[0];
-			}
-
-			throw new LicenseAquisitionException(error[0].getMessage());
-		}
-		
-		String res = result[0];
-		
-		return res;
-		
-	}
-	
-	public void aquireLicenseFor(String contentHash) throws LicenseAquisitionException,ExceededDRMDeliveryLimitException,DRMUpdateRequiredException {
-		String systemInfo = getSystemInfo();
-		String license = null;
-		try {
-			license = getLicenseFromPlatform(systemInfo, contentHash);
-		} catch (CheckVersionRequiredException e) {
-			checkDRMSystem();
-		}
-		if(license != null) {
-			storeLicense(license);
-		} else {
-			throw new LicenseAquisitionException("failed to aquire a license");
-		}
-		System.out.println("license aquired");
-	}
-	
-	public boolean checkDRMSystem() throws LicenseAquisitionException,DRMUpdateRequiredException {
-		String systemInfo = getSystemInfo();
-		String drmVersion = getDRMVersion();
-		
-		return checkDRMVersion(systemInfo, drmVersion);
-		
-	}
-	
-	public static void main(String args[]) throws Exception {
-		Display display = new Display();
-		final Shell shell = new Shell(display);
-		//shell.setLayout(new FillLayout());
-		shell.open();
-		final LicenseAquirer la = new LicenseAquirer(shell);
-		Thread t = new Thread() {
-			public void run() {
-				try {
-					la.aquireLicenseFor("SNWEAY7K6RJPAJF2HD52BEX27ERKJXAO");
-				} catch (Exception e) {
-					e.printStackTrace();
-				}
-			}
-		};
-		t.setDaemon(true);
-		t.start();
-		
-		while(!shell.isDisposed()) {
-			if(!display.readAndDispatch()){
-				display.sleep();
-			}
-		}
-		
-		display.dispose();
-	}
-
-}
diff --git a/com/aelitis/azureus/core/drm/msdrm/LicenseAquisitionException.java b/com/aelitis/azureus/core/drm/msdrm/LicenseAquisitionException.java
deleted file mode 100644
index c17f296..0000000
--- a/com/aelitis/azureus/core/drm/msdrm/LicenseAquisitionException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.aelitis.azureus.core.drm.msdrm;
-
-public class LicenseAquisitionException extends Exception {
-	
-	public LicenseAquisitionException(String message) {
-		super(message);
-	}
-
-}
diff --git a/com/aelitis/azureus/core/impl/AzureusCoreImpl.java b/com/aelitis/azureus/core/impl/AzureusCoreImpl.java
index 7849d3f..151940a 100644
--- a/com/aelitis/azureus/core/impl/AzureusCoreImpl.java
+++ b/com/aelitis/azureus/core/impl/AzureusCoreImpl.java
@@ -59,7 +59,6 @@ import com.aelitis.azureus.core.instancemanager.AZInstanceManager;
 import com.aelitis.azureus.core.instancemanager.AZInstanceManagerAdapter;
 import com.aelitis.azureus.core.instancemanager.AZInstanceManagerFactory;
 import com.aelitis.azureus.core.instancemanager.AZInstanceTracked;
-import com.aelitis.azureus.core.instancemanager.AZInstanceManagerAdapter.VCPublicAddress;
 import com.aelitis.azureus.core.nat.NATTraverser;
 import com.aelitis.azureus.core.networkmanager.NetworkManager;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
@@ -68,6 +67,7 @@ import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminNetworkInterfac
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminPropertyChangeListener;
 import com.aelitis.azureus.core.networkmanager.impl.tcp.TCPNetworkManager;
 import com.aelitis.azureus.core.networkmanager.impl.udp.UDPNetworkManager;
+import com.aelitis.azureus.core.pairing.PairingManagerFactory;
 import com.aelitis.azureus.core.peermanager.PeerManager;
 import com.aelitis.azureus.core.peermanager.nat.PeerNATTraverser;
 import com.aelitis.azureus.plugins.clientid.ClientIDPlugin;
@@ -242,7 +242,7 @@ AzureusCoreImpl
 			});
 		
 			//ensure early initialization
-		
+				
 		CustomizationManagerFactory.getSingleton();
 		
 		NetworkManager.getSingleton();
@@ -916,6 +916,8 @@ AzureusCoreImpl
 		   global_manager.resumeDownloads();
 	   }
 	    
+	   VersionCheckClient.getSingleton().initialise();
+
 	   instance_manager.initialize();
 
 	   NetworkManager.getSingleton().initialize(this); 
@@ -1023,6 +1025,8 @@ AzureusCoreImpl
 				return;
 			}
 
+	   PairingManagerFactory.getSingleton();
+	   
 	   Object[] runningListeners;
 	   mon_coreRunningListeners.enter();
 	   try {
@@ -1089,7 +1093,7 @@ AzureusCoreImpl
 			}
 		}
 		
-		Debug.out("Core Start Complete");
+		// Debug.out("Core Start Complete");
 	}
 
 	public boolean
@@ -1346,6 +1350,15 @@ AzureusCoreImpl
 				AzureusRestarterFactory.create( this ).restart( true );
 			}
 			
+			try {
+	      Class c = Class.forName( "sun.awt.AWTAutoShutdown" );
+	      
+	      if (c != null) {
+		      c.getMethod( "notifyToolkitThreadFree", new Class[]{} ).invoke( null, new Object[]{} );
+	      }
+			} catch (Throwable t) {
+			}
+			
 			try{
 				ThreadGroup	tg = Thread.currentThread().getThreadGroup();
 				
@@ -1357,7 +1370,7 @@ AzureusCoreImpl
 					
 					final Thread	t = threads[i];
 					
-					if ( t != null && t != Thread.currentThread() && !t.isDaemon() && !AEThread2.isOurThread( t )){
+					if ( t != null && t.isAlive() && t != Thread.currentThread() && !t.isDaemon() && !AEThread2.isOurThread( t )){
 						
 						new AEThread2( "VMKiller", true )
 						{
@@ -1366,7 +1379,7 @@ AzureusCoreImpl
 							{
 								try{
 									Thread.sleep(10*1000);
-								
+									
 									Debug.out( "Non-daemon thread found '" + t.getName() + "', force closing VM" );
 									
 									SESecurityManager.exitVM(0);
diff --git a/com/aelitis/azureus/core/lws/LWSDiskManager.java b/com/aelitis/azureus/core/lws/LWSDiskManager.java
index a2ea0f3..63059dc 100644
--- a/com/aelitis/azureus/core/lws/LWSDiskManager.java
+++ b/com/aelitis/azureus/core/lws/LWSDiskManager.java
@@ -585,9 +585,8 @@ LWSDiskManager
 		return( disk_access_controller );
 	}
 	
-	public DMPieceList
-	getPieceList(
-		int	piece_number )
+	public DMPieceMap  
+	getPieceMap()
 	{
 		DMPieceMap	map = piece_map_use_accessor;
 		
@@ -596,9 +595,19 @@ LWSDiskManager
 			piece_map_use_accessor = map = piece_mapper.getPieceMap();			
 		}
 		
+		return( map );
+	}
+	
+	public DMPieceList
+	getPieceList(
+		int	piece_number )
+	{
+		DMPieceMap	map = getPieceMap();
+		
 		return( map.getPieceList( piece_number ));
 	}
 		
+	
 	protected DMChecker
 	getChecker()
 	{
diff --git a/com/aelitis/azureus/core/lws/LWSDiskManagerState.java b/com/aelitis/azureus/core/lws/LWSDiskManagerState.java
index 984835b..b0964ec 100644
--- a/com/aelitis/azureus/core/lws/LWSDiskManagerState.java
+++ b/com/aelitis/azureus/core/lws/LWSDiskManagerState.java
@@ -123,6 +123,13 @@ LWSDiskManagerState
 	{
 		return( false );
 	}
+	
+	public long 
+	getFlags() 
+	{
+		return 0;
+	}
+	
 	public boolean 
 	isOurContent() 
 	{
diff --git a/com/aelitis/azureus/core/lws/LWSDownload.java b/com/aelitis/azureus/core/lws/LWSDownload.java
index fb51848..1b10073 100644
--- a/com/aelitis/azureus/core/lws/LWSDownload.java
+++ b/com/aelitis/azureus/core/lws/LWSDownload.java
@@ -186,6 +186,12 @@ LWSDownload
 		return( false );
 	}
 	
+	public long 
+	getFlags() 
+	{
+		return 0;
+	}
+	
 	public int
 	getIndex()
 	{
diff --git a/com/aelitis/azureus/core/lws/LWSTorrent.java b/com/aelitis/azureus/core/lws/LWSTorrent.java
index 3fd4cb5..6b50654 100644
--- a/com/aelitis/azureus/core/lws/LWSTorrent.java
+++ b/com/aelitis/azureus/core/lws/LWSTorrent.java
@@ -136,6 +136,13 @@ LWSTorrent
 		return( getDelegate().getCreatedBy());
 	}
 	
+  	public void
+	setCreatedBy(
+		byte[]		cb )
+   	{
+  		getDelegate().setCreatedBy( cb );
+   	}
+  	
 	public boolean
 	isCreated()
 	{
diff --git a/com/aelitis/azureus/core/messenger/ClientMessageContext.java b/com/aelitis/azureus/core/messenger/ClientMessageContext.java
index ae6216b..a792585 100644
--- a/com/aelitis/azureus/core/messenger/ClientMessageContext.java
+++ b/com/aelitis/azureus/core/messenger/ClientMessageContext.java
@@ -23,10 +23,7 @@ package com.aelitis.azureus.core.messenger;
 import java.util.Collection;
 import java.util.Map;
 
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.messenger.browser.BrowserMessageDispatcher;
-import com.aelitis.azureus.core.messenger.browser.BrowserTransaction;
-import com.aelitis.azureus.core.messenger.browser.BrowserTransactionManager;
 import com.aelitis.azureus.core.messenger.browser.listeners.BrowserMessageListener;
 
 /**
@@ -42,16 +39,6 @@ public interface ClientMessageContext
 
 	public abstract void removeMessageListener(BrowserMessageListener listener);
 
-	public abstract BrowserTransactionManager getTransactionManager();
-
-	public abstract void registerTransactionType(String type, Class clazz);
-
-	public abstract BrowserTransaction getTransaction(String type);
-
-	public abstract BrowserTransaction startTransaction(String type);
-
-	public abstract BrowserTransaction cancelTransaction(String type);
-
 	public abstract Object getBrowserData(String key);
 
 	public abstract void setBrowserData(String key, Object value);
diff --git a/com/aelitis/azureus/core/messenger/ClientMessageContextImpl.java b/com/aelitis/azureus/core/messenger/ClientMessageContextImpl.java
index 7b50588..d34a842 100644
--- a/com/aelitis/azureus/core/messenger/ClientMessageContextImpl.java
+++ b/com/aelitis/azureus/core/messenger/ClientMessageContextImpl.java
@@ -25,8 +25,6 @@ import org.gudy.azureus2.core3.util.AEDiagnosticsLogger;
 import org.gudy.azureus2.core3.util.Debug;
 
 import com.aelitis.azureus.core.messenger.browser.BrowserMessageDispatcher;
-import com.aelitis.azureus.core.messenger.browser.BrowserTransaction;
-import com.aelitis.azureus.core.messenger.browser.BrowserTransactionManager;
 import com.aelitis.azureus.core.messenger.browser.listeners.BrowserMessageListener;
 import com.aelitis.azureus.util.ConstantsVuze;
 
@@ -42,12 +40,9 @@ public abstract class ClientMessageContextImpl
 
 	private BrowserMessageDispatcher dispatcher;
 
-	private BrowserTransactionManager txnManager;
-
 	public ClientMessageContextImpl(String id, BrowserMessageDispatcher dispatcher) {
 		this.id = id;
 		this.dispatcher = dispatcher;
-		this.txnManager = new BrowserTransactionManager(this);
 	}
 
 	public void addMessageListener(BrowserMessageListener listener) {
@@ -59,10 +54,6 @@ public abstract class ClientMessageContextImpl
 		}
 	}
 
-	public BrowserTransaction cancelTransaction(String type) {
-		return txnManager.cancelTransaction(type);
-	}
-
 	public void debug(String message) {
 		AEDiagnosticsLogger diag_logger = AEDiagnostics.getLogger("v3.CMsgr");
 		diag_logger.log("[" + id + "] " + message);
@@ -81,18 +72,6 @@ public abstract class ClientMessageContextImpl
 		}
 	}
 
-	public BrowserTransaction getTransaction(String type) {
-		return txnManager.getTransaction(type);
-	}
-
-	public BrowserTransactionManager getTransactionManager() {
-		return txnManager;
-	}
-
-	public void registerTransactionType(String type, Class clazz) {
-		txnManager.registerTransactionType(type, clazz);
-	}
-
 	public void removeMessageListener(String listenerId) {
 		if (dispatcher != null) {
 			dispatcher.removeListener(listenerId);
@@ -111,10 +90,6 @@ public abstract class ClientMessageContextImpl
 		}
 	}
 
-	public BrowserTransaction startTransaction(String type) {
-		return txnManager.startTransaction(type);
-	}
-
 	public BrowserMessageDispatcher getDispatcher() {
 		return dispatcher;
 	}
diff --git a/com/aelitis/azureus/core/messenger/PlatformMessage.java b/com/aelitis/azureus/core/messenger/PlatformMessage.java
index 78e2bc4..b747a03 100644
--- a/com/aelitis/azureus/core/messenger/PlatformMessage.java
+++ b/com/aelitis/azureus/core/messenger/PlatformMessage.java
@@ -26,9 +26,7 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.SystemTime;
 
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.login.NotLoggedInException;
 import com.aelitis.azureus.util.JSONUtils;
-import com.aelitis.azureus.util.LoginInfoManager;
 
 /**
  * @author TuxPaper
@@ -168,46 +166,6 @@ public class PlatformMessage
 						: paramString) + "}";
 	}
 
-	/**
-	 * @param requiresAuthorization the requiresAuthorization to set
-	 * @throws NotLoggedInException 
-	 */
-	public void setRequiresAuthorization(boolean requiresAuthorization,
-			boolean promptUser)
-			throws NotLoggedInException {
-		this.requiresAuthorization = requiresAuthorization;
-		this.loginAndRetry = promptUser;
-
-		if (!promptUser && !LoginInfoManager.getInstance().isLoggedIn()) {
-			throw new NotLoggedInException();
-		}
-	}
-
-	public void setRequiresAuthorizationNoCheck() {
-		this.requiresAuthorization = true;
-	}
-
-	/**
-	 * @return the requiresAuthorization
-	 */
-	public boolean requiresAuthorization() {
-		return requiresAuthorization;
-	}
-
-	/**
-	 * @param loginAndRetry the loginAndRetry to set
-	 */
-	public void setLoginAndRetry(boolean loginAndRetry) {
-		this.loginAndRetry = loginAndRetry;
-	}
-
-	/**
-	 * @return the loginAndRetry
-	 */
-	public boolean getLoginAndRetry() {
-		return loginAndRetry;
-	}
-
 	public String toShortString() {
 		return (requiresAuthorization ? "AUTH: " : "") + getMessageID() + "."
 				+ getListenerID() + "." + getOperationID();
diff --git a/com/aelitis/azureus/core/messenger/PlatformMessenger.java b/com/aelitis/azureus/core/messenger/PlatformMessenger.java
index e9f7252..7af8387 100644
--- a/com/aelitis/azureus/core/messenger/PlatformMessenger.java
+++ b/com/aelitis/azureus/core/messenger/PlatformMessenger.java
@@ -24,25 +24,19 @@ import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.URL;
 import java.net.URLEncoder;
-import java.text.NumberFormat;
 import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Timer;
 import org.gudy.azureus2.plugins.utils.StaticUtilities;
 import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
 import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderException;
 import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderFactory;
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
 
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.core.messenger.browser.BrowserMessageDispatcher;
-import com.aelitis.azureus.core.messenger.browser.listeners.MessageCompletionListener;
-import com.aelitis.azureus.core.messenger.config.PlatformRelayMessenger;
 import com.aelitis.azureus.util.*;
 
 /**
@@ -72,14 +66,10 @@ public class PlatformMessenger
 	/** Key: id of queue;  Value: Map of queued messages & listeners */
 	static private Map<String, Map> mapQueues = new HashMap();
 
-	private static final String QUEUE_AUTH = "Auth.";
-
 	private static final String QUEUE_NOAZID = "noazid.";
 
 	private static final String QUEUE_NORMAL = "msg.";
 
-	private static final String QUEUE_RELAY = "relay.";
-
 	static private AEMonitor queue_mon = new AEMonitor(
 			"v3.PlatformMessenger.queue");
 
@@ -95,9 +85,9 @@ public class PlatformMessenger
 
 	private static fakeContext context;
 
-	private static PlatformAuthorizedSender authorizedSender;
+	private static boolean allowMulti = false;
 
-	private static boolean authorizedDelayed;
+	private static AsyncDispatcher	dispatcher = new AsyncDispatcher(5000);
 	
 	public static synchronized void init() {
 		if (initialized) {
@@ -109,16 +99,6 @@ public class PlatformMessenger
 		context = new fakeContext();
 	}
 
-	public static void setAuthorizedTransferListener(
-			PlatformAuthorizedSender authorizedSender) {
-		debug("set Authorized Sender");
-		PlatformMessenger.authorizedSender = authorizedSender;
-	}
-
-	public static PlatformAuthorizedSender getAuthorizedTransferListener() {
-		return PlatformMessenger.authorizedSender;
-	}
-
 	public static ClientMessageContext getClientMessageContext() {
 		if (!initialized) {
 			init();
@@ -156,17 +136,10 @@ public class PlatformMessenger
 					debug("Content Network invalid for " + message);
 					return;
 				}
-				if (message.requiresAuthorization()) {
-					queueID = QUEUE_AUTH;
-				} else if (!message.sendAZID()) {
+				if (!message.sendAZID()) {
 					queueID = QUEUE_NOAZID;
 				} else {
-					boolean isRelayServer = PlatformRelayMessenger.LISTENER_ID.equals(message.getListenerID());
-					if (isRelayServer) {
-						queueID = QUEUE_RELAY;
-					} else {
-						queueID = QUEUE_NORMAL;
-					}
+					queueID = QUEUE_NORMAL;
 				}
 				queueID += networkID;
 				
@@ -181,9 +154,6 @@ public class PlatformMessenger
 						+ message.toShortString() + ": " + message + " @ "
 						+ new Date(message.getFireBefore()) + "; in "
 						+ (message.getFireBefore() - SystemTime.getCurrentTime()) + "ms");
-				if (message.requiresAuthorization() && authorizedDelayed) {
-					debug("   authorized msg is delayed");
-				}
 
 				fireBefore = message.getFireBefore();
 			} else {
@@ -287,27 +257,32 @@ public class PlatformMessenger
 		
 		final Map mapProcessing = new HashMap();
 
-		boolean loginAndRetry = false;
-		boolean requiresAuthorization = false;
 		boolean sendAZID = true;
 		long contentNetworkID = ContentNetwork.CONTENT_NETWORK_VUZE;
 
 		// Create urlStem (or post data)
-		// determine which server to use
-		String server = null;
+		boolean isMulti = false;
 		StringBuffer urlStem = new StringBuffer();
 		long sequenceNo = 0;
 
+		Map<String, Object> mapPayload = new HashMap<String, Object>();
+		mapPayload.put("azid", ConstantsVuze.AZID);
+		mapPayload.put("azv", Constants.AZUREUS_VERSION);
+		List<Map> listCommands = new ArrayList<Map>();
+		mapPayload.put("commands", listCommands);
+
 		queue_mon.enter();
 		try {
+			String lastServer = null;
 			// add one at a time, ensure relay server messages are seperate
 			boolean first = true;
 			for (Iterator iter = mapQueue.keySet().iterator(); iter.hasNext();) {
 				PlatformMessage message = (PlatformMessage) iter.next();
 				Object value = mapQueue.get(message);
+				
+				Map<String, Object> mapCmd = new HashMap<String, Object>();
 
 				if (first) {
-					requiresAuthorization = message.requiresAuthorization();
 					sendAZID = message.sendAZID();
 					contentNetworkID = message.getContentNetworkID();
 					first = false;
@@ -316,44 +291,44 @@ public class PlatformMessenger
 				// build urlStem
 				message.setSequenceNo(sequenceNo);
 
-				StringBuffer urlStemSegment = new StringBuffer();
-				if (sequenceNo > 0) {
-					urlStemSegment.append('&');
+				if (urlStem.length() > 0) {
+					urlStem.append('&');
 				}
 
 				String listenerID = message.getListenerID();
 				String messageID = message.getMessageID();
-				String params = message.getParameters().toString();
+				Map params = message.getParameters();
 				try {
-					urlStemSegment.append("cmd=");
-					urlStemSegment.append(URLEncoder.encode(messageID, "UTF-8"));
-					urlStemSegment.append(BrowserMessage.MESSAGE_DELIM_ENCODED);
-					urlStemSegment.append(sequenceNo);
-					urlStemSegment.append(BrowserMessage.MESSAGE_DELIM_ENCODED);
-					urlStemSegment.append(URLEncoder.encode(listenerID, "UTF-8"));
-					urlStemSegment.append(BrowserMessage.MESSAGE_DELIM_ENCODED);
-					urlStemSegment.append(URLEncoder.encode(message.getOperationID(),
+					urlStem.append("msg=");
+					urlStem.append(URLEncoder.encode(listenerID, "UTF-8"));
+					urlStem.append(":");
+					urlStem.append(URLEncoder.encode(message.getOperationID(),
 							"UTF-8"));
-					urlStemSegment.append(BrowserMessage.MESSAGE_DELIM_ENCODED);
-					urlStemSegment.append(URLEncoder.encode(params, "UTF-8"));
 				} catch (UnsupportedEncodingException e) {
 				}
+				
+				mapCmd.put("seq-id", sequenceNo);
+				mapCmd.put("listener-id", listenerID);
+				mapCmd.put("op-id", message.getOperationID());
+				if (params != null) {
+					mapCmd.put("values", params);
+				}
+				listCommands.add(mapCmd);
 
-				if (sequenceNo > 0
-						&& urlStem.length() + urlStemSegment.length() > MAX_POST_LENGTH) {
+				// We used to check on MAX_POST_LENGTH, but with the changes that
+				// would require converting the map to JSON on every iteration to get
+				// the length.  For now, just limit to 10
+				if (sequenceNo > 10) {
 					debug("breaking up batch at " + sequenceNo
-							+ " because max limit would be exceeded (" + urlStem.length()
-							+ " + " + urlStemSegment.length() + ")");
+							+ " because max limit would be exceeded");
 					break;
 				}
 
-				urlStem.append(urlStemSegment);
 				String curServer = messageID + "-" + listenerID;
-				if (server == null) {
-					server = curServer;
-				} else if (!server.equals(curServer)) {
-					server = "multi";
+				if (lastServer != null && !lastServer.equals(curServer)) {
+					isMulti = true;
 				}
+				lastServer = curServer;
 
 				PlatformMessengerListener listener = (PlatformMessengerListener) mapProcessing.get(message);
 				if (listener != null) {
@@ -365,14 +340,9 @@ public class PlatformMessenger
 				mapProcessing.put(message, value);
 
 				iter.remove();
-
-				// split up ones that requre login and retry and ones that don't
-				if (mapProcessing.size() == 1) {
-					loginAndRetry = message.getLoginAndRetry();
-				} else {
-					if (loginAndRetry != message.getLoginAndRetry()) {
-						break;
-					}
+				
+				if (!getAllowMulti() ) {
+					break;
 				}
 			}
 		} finally {
@@ -384,10 +354,6 @@ public class PlatformMessenger
 			return;
 		}
 
-		if (server == null) {
-			server = "default";
-		}
-
 		// Build base RPC url based on listener and server
 
 		// one day all this URL hacking should be moved into the ContentNetwork...
@@ -398,43 +364,27 @@ public class PlatformMessenger
 			cn = ConstantsVuze.getDefaultContentNetwork();
 		}
 
-		String sURL_RPC;
-		boolean isRelayServer = (PlatformRelayMessenger.MSG_ID + "-" + PlatformRelayMessenger.LISTENER_ID).equals(server);
-		if (isRelayServer) {
-
-			sURL_RPC = ContentNetworkUtils.getUrl(cn, ContentNetwork.SERVICE_RELAY_RPC);
-
-		} else {
-			sURL_RPC = ContentNetworkUtils.getUrl(cn, ContentNetwork.SERVICE_RPC)
-					+ server;
-		}
+		String sURL_RPC = ContentNetworkUtils.getUrl(cn, ContentNetwork.SERVICE_RPC)
+					+ "?" + urlStem.toString();
 
 		// Build full url and data to send
 		String sURL;
 		String sPostData = null;
-		if (USE_HTTP_POST || requiresAuthorization) {
+		String sJSONPayload = UrlUtils.encode(JSONUtils.encodeToJSON(mapPayload));
+		if (USE_HTTP_POST) {
 			sURL = sURL_RPC;
-			if (requiresAuthorization) {
-				String sAuthUrl = ContentNetworkUtils.getUrl(cn,
-						ContentNetwork.SERVICE_AUTH_RPC);
-				if (sAuthUrl != null) {
-					sURL = sAuthUrl;
-				}
-			}
 
-			sPostData = URL_POST_PLATFORM_DATA + "&" + urlStem.toString();
+			sPostData = URL_POST_PLATFORM_DATA + "&payload=" + sJSONPayload;
 			sPostData = cn.appendURLSuffix(sPostData, true, sendAZID);
 
-			if (!requiresAuthorization) {
-				if (DEBUG_URL) {
-					debug("POST for " + mapProcessing.size() + ": " + sURL + "?"
-							+ sPostData);
-				} else {
-					debug("POST for " + mapProcessing.size() + ": " + sURL);
-				}
+			if (DEBUG_URL) {
+				debug("POST for " + mapProcessing.size() + ": " + sURL + "\n   DATA: "
+						+ sPostData);
+			} else {
+				debug("POST for " + mapProcessing.size() + ": " + sURL);
 			}
 		} else {
-			sURL = sURL_RPC + URL_PLATFORM_MESSAGE + "&" + urlStem.toString();
+			sURL = sURL_RPC + URL_PLATFORM_MESSAGE + "&payload=" + sJSONPayload;
 
 			sURL = cn.appendURLSuffix(sURL, false, sendAZID);
 
@@ -447,39 +397,41 @@ public class PlatformMessenger
 
 		final String fURL = sURL;
 		final String fPostData = sPostData;
-		final boolean fLoginAndRetry = loginAndRetry;
-		final boolean fReqAuth = requiresAuthorization;
 
-		// proccess queue on a new thread
-		AEThread2 thread = new AEThread2("v3.PlatformMessenger", true) {
-			public void run() {
-				try {
-					processQueueAsync(fURL, fPostData, mapProcessing, fReqAuth,
-							fLoginAndRetry);
-				} catch (Throwable e) {
-					if (e instanceof ResourceDownloaderException) {
-						debug("Error while sending message(s) to Platform: " + e.toString());
-					} else {
-						debug("Error while sending message(s) to Platform", e);
-					}
-					for (Iterator iter = mapProcessing.keySet().iterator(); iter.hasNext();) {
-						PlatformMessage message = (PlatformMessage) iter.next();
-						PlatformMessengerListener l = (PlatformMessengerListener) mapProcessing.get(message);
-						if (l != null) {
-							try {
-								HashMap map = new HashMap();
-								map.put("text", e.toString());
-								map.put("Throwable", e);
-								l.replyReceived(message, REPLY_EXCEPTION, map);
-							} catch (Throwable e2) {
-								debug("Error while sending replyReceived", e2);
+			// one at a time to take advantage of keep-alive connections
+		
+		dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void 
+				runSupport() 
+				{
+					try {
+						processQueueAsync(fURL, fPostData, mapProcessing);
+					} catch (Throwable e) {
+						if (e instanceof ResourceDownloaderException) {
+							debug("Error while sending message(s) to Platform: " + e.toString());
+						} else {
+							debug("Error while sending message(s) to Platform", e);
+						}
+						for (Iterator iter = mapProcessing.keySet().iterator(); iter.hasNext();) {
+							PlatformMessage message = (PlatformMessage) iter.next();
+							PlatformMessengerListener l = (PlatformMessengerListener) mapProcessing.get(message);
+							if (l != null) {
+								try {
+									HashMap map = new HashMap();
+									map.put("text", e.toString());
+									map.put("Throwable", e);
+									l.replyReceived(message, REPLY_EXCEPTION, map);
+								} catch (Throwable e2) {
+									debug("Error while sending replyReceived", e2);
+								}
 							}
 						}
 					}
 				}
-			}
-		};
-		thread.start();
+			});
+
 	}
 
 	/**
@@ -488,29 +440,18 @@ public class PlatformMessenger
 	 * @throws Exception 
 	 */
 	protected static void processQueueAsync(String sURL, String sData,
-			Map mapProcessing, boolean requiresAuthorization, boolean loginAndRetry)
-			throws Exception {
+			Map mapProcessing) throws Exception {
 		URL url;
 		url = new URL(sURL);
 
 		String s;
-		if (requiresAuthorization && authorizedSender != null) {
-			AESemaphore sem_waitDL = new AESemaphore("Waiting for DL");
-			authorizedSender.startDownload(url, sData, sem_waitDL, loginAndRetry);
-			sem_waitDL.reserve();
-			s = authorizedSender.getResults();
-			authorizedSender.clearResults();
-		} else {
-			if (requiresAuthorization) {
-				debug("No Authorized Sender.. using non-auth request");
-			}
-			byte[] bytes = downloadURL(url, sData);
-			s = new String(bytes, "UTF8");
-		}
+		byte[] bytes = downloadURL(url, sData);
+		s = new String(bytes, "UTF8");
 
-		// Format: <sequence no> ; <classification> [; <results>] [ \n ]
+		Map mapAllReplies = JSONUtils.decodeJSON(s);
+		List listReplies = MapUtils.getMapList(mapAllReplies, "replies", null);
 
-		if (s == null || s.length() == 0 || !Character.isDigit(s.charAt(0))) {
+		if (mapAllReplies == null || listReplies == null || listReplies.isEmpty()) {
 			debug("Error while sending message(s) to Platform: reply: " + s
 					+ "\nurl: " + sURL + "\nPostData: " + sData);
 			for (Iterator iter = mapProcessing.keySet().iterator(); iter.hasNext();) {
@@ -530,155 +471,45 @@ public class PlatformMessenger
 			return;
 		}
 
-		Map mapSeqToBrowserMsg = new HashMap();
-
-		String[] replies = s.split("\\n");
-		for (int i = 0; i < replies.length; i++) {
-			String reply = replies[i];
-
-			final String[] replySections = reply.split(BrowserMessage.MESSAGE_DELIM,
-					3);
-			if (replySections.length < 2) {
-				continue;
-			}
-			long sequenceNo = NumberFormat.getInstance().parse(replySections[0]).longValue();
-
-			Map actionResults = null;
-
-			if (replySections.length == 3) {
-				try {
-					actionResults = JSONUtils.decodeJSON(replySections[2]);
-				} catch (Throwable e) {
-					debug("Error while sending message(s) to Platform: reply: " + s
-							+ "\nurl: " + sURL + "\nPostData: " + sData, e);
-				}
-			}
-
-			// Find PlatformMessage associated with sequence
-			// TODO: There's a better way to do this
-			PlatformMessage message = null;
-			PlatformMessengerListener listener = null;
-			for (Iterator iter = mapProcessing.keySet().iterator(); iter.hasNext();) {
-				PlatformMessage potentialMessage = (PlatformMessage) iter.next();
-				if (potentialMessage.getSequenceNo() == sequenceNo) {
-					message = potentialMessage;
-					listener = (PlatformMessengerListener) mapProcessing.get(message);
-				}
+		Map<Long, Map> mapOrder = new HashMap<Long, Map>();
+		for (Object reply : listReplies) {
+			if (reply instanceof Map) {
+				mapOrder.put(MapUtils.getMapLong((Map) reply, "seq-id", -1), (Map) reply);
 			}
-
-			if (message == null) {
-				debug("No message with sequence number " + sequenceNo);
+		}
+		for (Iterator iter = mapProcessing.keySet().iterator(); iter.hasNext();) {
+			PlatformMessage message = (PlatformMessage) iter.next();
+			PlatformMessengerListener l = (PlatformMessengerListener) mapProcessing.get(message);
+			if (l == null) {
 				continue;
 			}
-
-			debug("Got a " + reply.length() + " byte reply for "
-					+ message.toShortString() + "\n\t\t"
-					+ reply.substring(0, Math.min(8192, reply.length())));
-
-			final PlatformMessage fMessage = message;
-			final PlatformMessengerListener fListener = listener;
-			final Map fActionResults = actionResults;
-
-			// test
-			if (i == 0 && false) {
-				replySections[1] = "action";
-				actionResults = new JSONObject();
-				actionResults.put("retry-client-message", new Boolean(true));
-				JSONArray a = new JSONArray();
-				a.add("[AZMSG;1;display;open-url;{\"url\":\"http://yahoo.com\",\"width\":500,\"height\":200}]");
-				actionResults.put("messages", a);
+			Map mapReply = mapOrder.get(new Long(message.getSequenceNo()));
+			if (mapReply == null) {
+				debug("No reply for " + message.toShortString());
+			}
+			String replyType = MapUtils.getMapString(mapReply, "type", "payload");
+			Map payload;
+			if (replyType.equalsIgnoreCase("payload")) {
+				payload = MapUtils.getMapMap(mapReply, "payload", Collections.EMPTY_MAP);
+			} else {
+				payload = new HashMap();
+				payload.put("message", MapUtils.getMapString(mapReply, "message", "?"));
 			}
 
-			// Todo check array [1] for reply type
-
-			if (replySections[1].equals("action")) {
-				final BrowserMessageDispatcher dispatcher = context.getDispatcher();
-				if (dispatcher == null) {
-					debug("action requested.. no dispatcher");
-				} else if (actionResults instanceof Map) {
-					final boolean bRetry = MapUtils.getMapBoolean(actionResults,
-							"retry-client-message", false);
-
-					List array = (List) MapUtils.getMapObject(actionResults, "messages",
-							null, List.class);
-					if (actionResults.containsKey("messages")) {
-						for (int j = 0; j < array.size(); j++) {
-							final String sMsg = (String) array.get(j);
-							debug("handling (" + ((bRetry) ? " with retry" : " no retry")
-									+ "): " + sMsg);
-
-							final BrowserMessage browserMsg = new BrowserMessage(sMsg);
-							int seq = browserMsg.getSequence();
-							BrowserMessage existingBrowserMsg = (BrowserMessage) mapSeqToBrowserMsg.get(new Long(
-									seq));
-							if (existingBrowserMsg != null) {
-								existingBrowserMsg.addCompletionListener(new MessageCompletionListener() {
-									public void completed(boolean success, Object data) {
-										debug("got complete for " + sMsg);
-										if (success) {
-											queueMessage(fMessage, fListener);
-										} else {
-											if (fListener != null) {
-												try {
-													fListener.replyReceived(fMessage, replySections[1],
-															fActionResults);
-												} catch (Throwable e2) {
-													debug("Error while sending replyReceived", e2);
-												}
-											}
-										}
-									}
-								});
-								continue;
-							}
-
-							if (bRetry) {
-								mapSeqToBrowserMsg.put(new Long(seq), browserMsg);
-
-								browserMsg.addCompletionListener(new MessageCompletionListener() {
-									public void completed(boolean success, Object data) {
-										debug("got complete for " + sMsg + ";" + success);
-										if (success) {
-											queueMessage(fMessage, fListener);
-										} else {
-											if (fListener != null) {
-												try {
-													fListener.replyReceived(fMessage, replySections[1],
-															fActionResults);
-												} catch (Throwable e2) {
-													debug("Error while sending replyReceived", e2);
-												}
-											}
-										}
-									}
-								});
-							}
-
-							new AEThread2("v3.Msg.Dispatch", true) {
-								public void run() {
-									dispatcher.dispatch(browserMsg);
-								}
-							}.start();
-						}
-					}
-					if (bRetry) {
-						continue;
-					}
-				}
+			
+			if (mapReply != null) {
+  			String reply = JSONUtils.encodeToJSON(payload);
+  			debug("Got a reply for "
+  					+ message.toShortString() + "\n\t"
+  					+ reply.substring(0, Math.min(8192, reply.length())));
 			}
 
-			if (listener != null) {
-				try {
-					listener.replyReceived(message, replySections[1], actionResults);
-				} catch (Exception e2) {
-					debug("Error while sending replyReceived", e2);
-				}
+			try {
+				l.replyReceived(message, replyType, payload);
+			} catch (Exception e2) {
+				debug("Error while sending replyReceived", e2);
 			}
 		}
-		BrowserMessageDispatcher dispatcher = context.getDispatcher();
-		if (dispatcher != null) {
-			dispatcher.resetSequence();
-		}
 	}
 
 	private static byte[] downloadURL(URL url, String postData)
@@ -687,6 +518,8 @@ public class PlatformMessenger
 
 		ResourceDownloader rd = rdf.create(url, postData);
 
+		rd.setProperty( "URL_Connection", "Keep-Alive" );
+		
 		rd = rdf.getRetryDownloader(rd, 3);
 		// We could report percentage to listeners, but there's no need to atm
 		//		rd.addListener(new ResourceDownloaderListener() {
@@ -726,6 +559,14 @@ public class PlatformMessenger
 		return (data);
 	}
 
+	public static void setAllowMulti(boolean allowMulti) {
+		PlatformMessenger.allowMulti = allowMulti;
+	}
+
+	public static boolean getAllowMulti() {
+		return allowMulti;
+	}
+
 	private static class fakeContext
 		extends ClientMessageContextImpl
 	{
@@ -793,38 +634,4 @@ public class PlatformMessenger
 			this.contentNetworkID = contentNetwork;
 		}
 	}
-
-	/**
-	 * @param b
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void setAuthorizedDelayed(boolean authorizedDelayed) {
-		debug("setDelayAuthorized " + authorizedDelayed);
-		PlatformMessenger.authorizedDelayed = authorizedDelayed;
-		if (!authorizedDelayed) {
-			boolean fireQueue = false;
-			queue_mon.enter();
-			try {
-				for (String key : mapQueues.keySet()) {
-					if (key.startsWith(QUEUE_AUTH)) {
-						Map map = mapQueues.get(key);
-						if (map != null && map.size() > 0) {
-							fireQueue = true;
-							break;
-						}
-					}
-				}
-			} finally {
-				queue_mon.exit();
-			}
-			if (fireQueue) {
-				queueMessage(null, null);
-			}
-		}
-	}
-
-	public static boolean isAuthorizedDelayed() {
-		return authorizedDelayed;
-	}
 }
diff --git a/com/aelitis/azureus/core/messenger/browser/BrowserMessage.java b/com/aelitis/azureus/core/messenger/browser/BrowserMessage.java
index 469a96e..c02d987 100644
--- a/com/aelitis/azureus/core/messenger/browser/BrowserMessage.java
+++ b/com/aelitis/azureus/core/messenger/browser/BrowserMessage.java
@@ -30,7 +30,6 @@ import org.gudy.azureus2.core3.util.Debug;
 import com.aelitis.azureus.core.messenger.browser.listeners.BrowserMessageListener;
 import com.aelitis.azureus.core.messenger.browser.listeners.MessageCompletionListener;
 import com.aelitis.azureus.util.ConstantsVuze;
-import com.aelitis.azureus.util.JSFunctionParametersParser;
 import com.aelitis.azureus.util.JSONUtils;
 
 /**
@@ -58,9 +57,6 @@ public class BrowserMessage
 	/** Parameters were an encoded JSONArray. */
 	public static final int ARRAY_PARAM = 2;
 
-	/** Parameters were an encoded list. */
-	public static final int LIST_PARAM = 3;
-	
 	static {
 		try {
 			MESSAGE_DELIM_ENCODED = URLEncoder.encode(";", "UTF-8");
@@ -155,13 +151,6 @@ public class BrowserMessage
 		return (List) decodedParams;
 	}
 
-	public List getDecodedList() {
-		if (!isParamList()) {
-			throw new IllegalStateException("Decoded parameter is not a List");
-		}
-		return (List) decodedParams;
-	}
-
 	public Map getDecodedMap() {
 		if (!isParamObject()) {
 			throw new IllegalStateException("Decoded parameter is not a Map");
@@ -219,10 +208,6 @@ public class BrowserMessage
 		return paramType == ARRAY_PARAM;
 	}
 
-	public boolean isParamList() {
-		return paramType == LIST_PARAM;
-	}
-
 	public boolean isParamObject() {
 		return paramType == OBJECT_PARAM;
 	}
@@ -298,11 +283,6 @@ public class BrowserMessage
 							decodedParams = null;
 						}
 						break;
-
-					default:
-						paramType = LIST_PARAM;
-						decodedParams = JSFunctionParametersParser.parse(params);
-						break;
 				}
 			} catch (Exception e) {
 				decodedParams = null;
diff --git a/com/aelitis/azureus/core/messenger/browser/BrowserTransaction.java b/com/aelitis/azureus/core/messenger/browser/BrowserTransaction.java
deleted file mode 100644
index 5230c85..0000000
--- a/com/aelitis/azureus/core/messenger/browser/BrowserTransaction.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Created on Jul 19, 2006 10:16:26 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.core.messenger.browser;
-
-import java.util.Map;
-
-import com.aelitis.azureus.core.messenger.ClientMessageContext;
-
-/**
- * Encapsulates a single transaction that interacts with a single
- * SWT {@link org.eclipse.swt.browser.BrowserBrowser}, possibly across multiple pages.
- * 
- * Transactions are started after being created and cannot be restarted.
- * They can be marked as cancelled or completed while running.
- * Once stopped, they are left as either completed or cancelled.
- * 
- * Subclasses may override starting, canceling, and stopping to perform
- * their own specific actions and return <code>false</code> to abort.
- * 
- * @author dharkness
- * @created Jul 19, 2006
- */
-public abstract class BrowserTransaction
-{
-	private int id;
-
-	private String type;
-
-	private ClientMessageContext context;
-
-	private boolean running = false;
-
-	private boolean cancelled = false;
-
-	private boolean completed = false;
-
-	public BrowserTransaction(int id, String type, ClientMessageContext context) {
-		this.id = id;
-		this.type = type;
-		this.context = context;
-	}
-
-	/**
-	 * Marks this transaction as cancelled if it is running and not complete.
-	 * A transaction may be cancelled only once. After that, <code>false</code> is returned.
-	 */
-	public boolean cancel() {
-		debug("cancel");
-		if (!running || completed || cancelled) {
-			return false;
-		}
-
-		debug("canceling");
-		if (!canceling()) {
-			return false;
-		}
-
-		debug("cancelled");
-		cancelled = true;
-		context.getTransactionManager().removeTransaction(this);
-
-		return true;
-	}
-
-	/**
-	 * Performs subclass-specific initialization to cancel the transaction.
-	 * Return <code>false</code> to abort the cancellation.
-	 * 
-	 * @return whether or not the transaction can be cancelled
-	 */
-	protected boolean canceling() {
-		return true;
-	}
-
-	/**
-	 * Displays a debug message tagged with the context ID.
-	 * 
-	 * @param message sent to the debug log
-	 */
-	protected void debug(String message) {
-		context.debug("[" + this + "] " + message);
-	}
-
-	/**
-	 * Displays a debug message and exception tagged with the context ID.
-	 * 
-	 * @param message sent to the debug log
-	 * @param t exception to log with message
-	 */
-	protected void debug(String message, Throwable t) {
-		context.debug("[" + this + "] " + message, t);
-	}
-
-	/**
-	 * Executes the given Javascript code in the browser.
-	 * 
-	 * @param javascript the code to execute
-	 */
-	protected void executeInBrowser(String javascript) {
-		if (context.getTransaction(type) == this) {
-			context.executeInBrowser(javascript);
-		} else {
-			debug("Non-current transaction cannot execute: " + javascript);
-		}
-	}
-
-	public int getId() {
-		return id;
-	}
-
-	public String getType() {
-		return type;
-	}
-
-	/**
-	 * Returns <code>true</code> if this transaction has been cancelled.
-	 */
-	public boolean isCancelled() {
-		return cancelled;
-	}
-
-	/**
-	 * Returns <code>true</code> if this transaction has started and is still running.
-	 */
-	public boolean isCompleted() {
-		return completed;
-	}
-
-	/**
-	 * Returns <code>true</code> if this transaction has started and is still running.
-	 */
-	public boolean isRunning() {
-		return running;
-	}
-
-	/**
-	 * Sends a message to the JavaScript in the page.
-	 * 
-	 * @param key identifies the listener to receive the message
-	 * @param op identifies the operation to perform
-	 */
-	protected void sendBrowserMessage(String key, String op) {
-		sendBrowserMessage(key, op, null);
-	}
-
-	/**
-	 * Sends a message to the JavaScript in the page.
-	 * 
-	 * @param key identifies the listener to receive the message
-	 * @param op identifies the operation to perform
-	 * @param params optional message parameters
-	 */
-	protected void sendBrowserMessage(String key, String op, Map params) {
-		if (context.getTransaction(type) == this) {
-			context.sendBrowserMessage(key, op, params);
-		} else {
-			debug("Non-current transaction cannot send: " + key + "." + op);
-		}
-	}
-
-	/**
-	 * Starts the transaction if it is not yet running, completed or cancelled.
-	 * A transaction may be started only once. After that, <code>false</code> is returned.
-	 */
-	public boolean start() {
-		debug("start");
-		if (running || completed || cancelled) {
-			return false;
-		}
-
-		debug("starting");
-		if (!starting()) {
-			return false;
-		}
-
-		debug("started");
-		running = true;
-		return true;
-	}
-
-	/**
-	 * Performs subclass-specific initialization to start the transaction.
-	 * Return <code>false</code> to abort the start.
-	 * 
-	 * @return whether or not the transaction can start
-	 */
-	protected boolean starting() {
-		return true;
-	}
-
-	/**
-	 * Marks this transaction as completed if it is running and not cancelled.
-	 * If it is running and cancelled, it is simply marked as not running.
-	 * A transaction may be stopped only once. After that, <code>false</code> is returned.
-	 */
-	protected boolean stop() {
-		debug("stop");
-		if (!running) {
-			return false;
-		}
-
-		debug("stopping");
-		if (!stopping()) {
-			return false;
-		}
-
-		debug("stopped");
-		running = false;
-		completed = !cancelled;
-		context.getTransactionManager().removeTransaction(this);
-
-		return true;
-	}
-
-	/**
-	 * Performs subclass-specific initialization to stop the transaction.
-	 * Return <code>false</code> to abort the stop.
-	 * 
-	 * @return whether or not the transaction can be stopped
-	 */
-	protected boolean stopping() {
-		return true;
-	}
-
-	public String toString() {
-		return type + "-" + id + (running ? "-running" : "")
-				+ (cancelled ? "-cancelled" : "") + (completed ? "-completed" : "");
-	}
-}
diff --git a/com/aelitis/azureus/core/messenger/browser/BrowserTransactionManager.java b/com/aelitis/azureus/core/messenger/browser/BrowserTransactionManager.java
deleted file mode 100644
index 11bf60f..0000000
--- a/com/aelitis/azureus/core/messenger/browser/BrowserTransactionManager.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Created on Jul 19, 2006 10:16:26 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.core.messenger.browser;
-
-import java.lang.reflect.Constructor;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.aelitis.azureus.core.messenger.ClientMessageContext;
-
-/**
- * Manages the context for a single SWT {@link org.eclipse.swt.browser.Browser} component.
- * 
- * @author dharkness
- * @created Jul 19, 2006
- */
-public class BrowserTransactionManager
-{
-	private ClientMessageContext context;
-
-	// { "type" -> Constructor }
-	private Map txnCtors = new HashMap();
-
-	// { "type" -> Transaction }
-	private Map txns = new HashMap();
-
-	private int lastTxnId = 0;
-
-	public BrowserTransactionManager(ClientMessageContext context) {
-		this.context = context;
-	}
-
-	/**
-	 * Cancels the current transaction if there is one for this listener 
-	 * and the browser in the given message.
-	 * 
-	 * @param type used to determine the transaction to return
-	 * @return the current transaction or <code>null</code> if none exists
-	 */
-	public synchronized BrowserTransaction cancelTransaction(String type) {
-		BrowserTransaction txn = getTransaction(type);
-		if (txn != null) {
-			txn.cancel();
-		}
-
-		return txn;
-	}
-
-	/**
-	 * Creates a new transaction for this listener and the browser 
-	 * in the given message. If no transaction class was specified
-	 * in the constructor, subclasses must override this method.
-	 * 
-	 * @param message holds a reference to the browser
-	 * @return a new transaction
-	 */
-	protected BrowserTransaction createTransaction(String type) {
-		Constructor ctor = (Constructor) txnCtors.get(type);
-		if (ctor == null) {
-			throw new IllegalStateException("Unregistered transaction type: " + type);
-		}
-
-		try {
-			Object[] params = new Object[] {
-				new Integer(getNextTransactionId()),
-				type,
-				context
-			};
-			return (BrowserTransaction) ctor.newInstance(params);
-		} catch (Exception e) {
-			throw new RuntimeException("Exception creating transaction for type "
-					+ type, e);
-		}
-	}
-
-	/**
-	 * Increments the last transaction ID and returns the new value.
-	 * 
-	 * @return a unique ID to use for a new transaction
-	 */
-	private int getNextTransactionId() {
-		return ++lastTxnId;
-	}
-
-	/**
-	 * Returns the current transaction of the given type.
-	 * 
-	 * @param type used to locate the transaction
-	 * @return the transaction or <code>null</code> if none exists
-	 */
-	public synchronized BrowserTransaction getTransaction(String type) {
-		return (BrowserTransaction) txns.get(type);
-	}
-
-	/**
-	 * Registers the given transaction subclass as that to be created
-	 * for the given type identifier.
-	 * 
-	 * @param clazz used when creating transactions
-	 * 
-	 * @throws IllegalArgumentException if txnClass is null or not a subclass
-	 *              of {@link BrowserTransaction}
-	 * @throws IllegalArgumentException if the appropriate constructor 
-	 *              of txnClass cannot be found or accessed 
-	 */
-	public void registerTransactionType(String type, Class clazz) {
-		if (clazz == null) {
-			throw new IllegalArgumentException("Transaction class must be non-null");
-		}
-		if (!BrowserTransaction.class.isAssignableFrom(clazz)) {
-			throw new IllegalArgumentException("Transaction class " + clazz.getName()
-					+ " must be a subclass of Transaction");
-		}
-
-		try {
-			Class[] ctorParams = new Class[] {
-				Integer.TYPE,
-				String.class,
-				ClientMessageContext.class
-			};
-			Constructor ctor = clazz.getConstructor(ctorParams);
-			txnCtors.put(type, ctor);
-		} catch (Exception e) {
-			throw new IllegalArgumentException(
-					"Cannot access appropriate constructor for " + clazz.getName());
-		}
-	}
-
-	/**
-	 * Removes the given transaction from current status if it's current.
-	 * 
-	 * @param txn the Transaction to be removed
-	 * @return <code>true</code> if the transaction was current; <code>false</code> otherwise
-	 */
-	synchronized boolean removeTransaction(BrowserTransaction txn) {
-		if (txn != getTransaction(txn.getType())) {
-			return false;
-		}
-
-		return txns.remove(txn.getType()) == txn;
-	}
-
-	/**
-	 * Starts a new transaction of the given type after canceling
-	 * the current transaction if any.
-	 * 
-	 * @param type used to determine the transaction class to create
-	 * @return a new started transaction
-	 */
-	public synchronized BrowserTransaction startTransaction(String type) {
-		cancelTransaction(type);
-
-		BrowserTransaction txn = createTransaction(type);
-		if (txn != null) {
-			if (!txn.start()) {
-				return null;
-			}
-
-			txns.put(type, txn);
-		}
-
-		return txn;
-	}
-}
diff --git a/com/aelitis/azureus/core/messenger/browser/listeners/AbstractTransactionalListener.java b/com/aelitis/azureus/core/messenger/browser/listeners/AbstractTransactionalListener.java
deleted file mode 100644
index 2cbc5e9..0000000
--- a/com/aelitis/azureus/core/messenger/browser/listeners/AbstractTransactionalListener.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Created on Jul 19, 2006 10:16:26 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.core.messenger.browser.listeners;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.core.messenger.browser.BrowserTransaction;
-
-/**
- * A listener that requires a {@link BrowserTransaction} before
- * dispatching messages.
- * 
- * @author dharkness
- * @created Jul 19, 2006
- */
-public abstract class AbstractTransactionalListener
-	extends AbstractBrowserMessageListener
-{
-	/** Start a new transaction or use an existing one (like J2EE REQUIRED) */
-	public static final String TXN_REQUIRED = "Required";
-
-	/** Start a new transaction, aborting any existing one (like J2EE REQUIRES_NEW) */
-	public static final String TXN_REQUIRES_NEW = "RequiresNew";
-
-	/** Require an existing transaction, erroring if there isn't one (like J2EE MANDATORY) */
-	public static final String TXN_MANDATORY = "Mandatory";
-
-	/** Handle without a transaction, ignoring any existing one (like J2EE NOT_SUPPORTED) */
-	public static final String TXN_NONE = "NotSupported";
-
-	private String txnType;
-
-	// { "operation-id" -> "txn-state" }
-	private Map txnStatesByOp = new HashMap();
-
-	/**
-	 * Uses the listener's ID as the transaction type.
-	 * 
-	 * @param id uniquely identifies this listener to the dispatcher 
-	 *              and defines the transaction type
-	 */
-	public AbstractTransactionalListener(String id) {
-		this(id, id);
-	}
-
-	/**
-	 * Provides a transaction type different from the listener's ID.
-	 * 
-	 * @param id uniquely identifies this listener to the dispatcher
-	 * @param txnType used to access transactions via the context
-	 */
-	public AbstractTransactionalListener(String id, String txnType) {
-		super(id);
-		this.txnType = txnType;
-	}
-
-	/**
-	 * Cancels the current transaction if there is one for this listener.
-	 * 
-	 * @return the cancelled transaction or <code>null</code> if none exists
-	 */
-	protected BrowserTransaction cancelTransaction() {
-		return context.cancelTransaction(txnType);
-	}
-
-	/**
-	 * Returns the transaction state (attribute)
-	 * @param operationId
-	 * @return
-	 */
-	protected String getOperationTxnState(String operationId) {
-		return (String) txnStatesByOp.get(operationId);
-	}
-
-	/**
-	 * Returns the current transaction for this listener.
-	 * 
-	 * @return the current transaction or <code>null</code> if none exists
-	 */
-	protected BrowserTransaction getTransaction() {
-		return context.getTransaction(txnType);
-	}
-
-	/**
-	 * Returns the transaction type used by this listener.
-	 * 
-	 * @return the transaction type used by this listener
-	 */
-	public String getTransactionType() {
-		return txnType;
-	}
-
-	/**
-	 * Ensures the correct transaction state before handling the message.
-	 * 
-	 * @param message contains the operation ID used to lookup the transaction state
-	 */
-	public void handleMessage(BrowserMessage message) {
-		String state = getOperationTxnState(message.getOperationId());
-
-		if (state == null) {
-			context.debug("Ignoring message without transactional state: " + message);
-			return;
-		}
-
-		BrowserTransaction txn = getTransaction();
-		if (state.equals(TXN_REQUIRED)) {
-			// start new if none exists
-			if (txn == null) {
-				txn = startTransaction();
-			}
-		} else if (state.equals(TXN_REQUIRES_NEW)) {
-			// cancel current and start new
-			cancelTransaction();
-			txn = startTransaction();
-		} else if (state.equals(TXN_MANDATORY)) {
-			// use existing or error
-			if (txn == null) {
-				transactionStateViolated(message, state, null);
-				return;
-			}
-		} else if (state.equals(TXN_NONE)) {
-			// ignore existing
-			if (txn != null) {
-				txn = null;
-			}
-		} else {
-			context.debug("Ignoring message with invalid transactional state ("
-					+ state + "): " + message);
-			return;
-		}
-
-		if (txn != null) {
-			handleTxnlMessage(message, txn);
-		} else {
-			handleNonTxnlMessage(message);
-		}
-	}
-
-	/**
-	 * Handle a browser message that doesn't require a transaction.
-	 * Subclasses must override if they have any non-transactional operations.
-	 * 
-	 * @param message the mesage to be handled
-	 */
-	protected void handleNonTxnlMessage(BrowserMessage message) {
-
-	}
-
-	/**
-	 * Handle a browser message that require a transaction. Subclasses must
-	 * implement this method, otherwise they should extend {@link AbstractBrowserMessageListener}.
-	 * 
-	 * @param message the mesage to be handled
-	 * @param txn the current transaction
-	 */
-	protected abstract void handleTxnlMessage(BrowserMessage message,
-			BrowserTransaction txn);
-
-	private void registerOperation(String operationId, String txnState) {
-		txnStatesByOp.put(operationId, txnState);
-	}
-
-	protected void registerOperationTxnMandatory(String operationId) {
-		registerOperation(operationId, TXN_MANDATORY);
-	}
-
-	protected void registerOperationTxnNone(String operationId) {
-		registerOperation(operationId, TXN_NONE);
-	}
-
-	protected void registerOperationTxnRequired(String operationId) {
-		registerOperation(operationId, TXN_REQUIRED);
-	}
-
-	protected void registerOperationTxnRequiresNew(String operationId) {
-		registerOperation(operationId, TXN_REQUIRES_NEW);
-	}
-
-	/**
-	 * Starts a new transaction for this listener.
-	 * 
-	 * @return a new started transaction
-	 */
-	protected BrowserTransaction startTransaction() {
-		return context.startTransaction(txnType);
-	}
-
-	/**
-	 * Called when the necessary transactional state is not correct
-	 * for the given message. Override to handle the error more gracefully.
-	 * 
-	 * @param message the message being handled
-	 * @param state the state required by the message
-	 * @param txn the existing transaction or <code>null</code> if none
-	 */
-	protected void transactionStateViolated(BrowserMessage message, String state,
-			BrowserTransaction txn) {
-		throw new IllegalStateException("Transaction state violated - state: "
-				+ state + ", txn: " + txn);
-	}
-}
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformBuddyMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformBuddyMessenger.java
deleted file mode 100644
index a5615d4..0000000
--- a/com/aelitis/azureus/core/messenger/config/PlatformBuddyMessenger.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/**
- * Created on Apr 18, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.core.messenger.config;
-
-import java.util.*;
-
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.SystemTime;
-
-import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.activities.VuzeActivitiesEntryBuddyRequest;
-import com.aelitis.azureus.activities.VuzeActivitiesManager;
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.messenger.PlatformMessage;
-import com.aelitis.azureus.core.messenger.PlatformMessenger;
-import com.aelitis.azureus.core.messenger.PlatformMessengerListener;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.util.LoginInfoManager;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author TuxPaper
- * @created Apr 18, 2008
- *
- * TODO: poll invites occasionally
- */
-public class PlatformBuddyMessenger
-{
-	public static final String LISTENER_ID_BUDDY = "buddy";
-
-	public static final String LISTENER_ID_INVITE = "invite";
-
-	public static final String OP_SYNC = "sync";
-
-	public static final String OP_GETINVITES = "fetch";
-
-	public static final String OP_COUNTINVITES = "count";
-
-	public static final String OP_INVITE = "invite";
-
-	public static final String OP_REMOVEBUDDY = "ditch";
-
-	public static final String OP_STARTSHARE = "start-share";
-	
-	private static long lastSyncCheck = 0; 
-	
-	public static void sync(
-			final VuzeBuddySyncListener l)
-		throws NotLoggedInException {
-
-		sync(null, l);
-	}
-
-	public static void sync(
-			final String[] pks,
-			final VuzeBuddySyncListener l) 
-		throws NotLoggedInException {
-	
-		lastSyncCheck = SystemTime.getCurrentTime();
-
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID_BUDDY,
-				OP_SYNC, new Object[] {
-					"pks",
-					pks
-				}, 1000);
-		message.setRequiresAuthorization(true, false);
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-
-			public void messageSent(
-					PlatformMessage message) {
-			}
-
-			public void replyReceived(
-					PlatformMessage message,
-					String replyType,
-					Map reply) {
-				if (!replyType.equals(PlatformMessenger.REPLY_RESULT)) {
-					return;
-				}
-
-				long updateTime = SystemTime.getCurrentTime();
-
-				List buddies = MapUtils.getMapList(reply, "buddies", null);
-
-				try {
-  				if (buddies == null) {
-  					return;
-  				}
-  				
-  				if (buddies.size() > 0) {
-  					VuzeBuddyManager.setSaveDelayed(true);
-  				}
-  
-  				for (Iterator iter = buddies.iterator(); iter.hasNext();) {
-  					Map mapBuddy = (Map) iter.next();
-  
-  					String loginID = MapUtils.getMapString(mapBuddy, "login-id", null);
-  
-  					VuzeBuddy buddy = VuzeBuddyManager.getBuddyByLoginID(loginID);
-  					if (buddy != null) {
-  						buddy.loadFromMap(mapBuddy);
-  					} else {
-  						buddy = VuzeBuddyManager.createNewBuddy(mapBuddy, true);
-  					}
-  
-  					if (buddy != null) {
-  						buddy.setLastUpdated(updateTime);
-  					}
-  				}
-  
-  				if (pks == null) {
-  					VuzeBuddyManager.removeBuddiesOlderThan(updateTime, false);
-  				}
-					VuzeBuddyManager.setSaveDelayed(false);
-				} finally {
-  				if (l != null) {
-  					l.syncComplete();
-  				}
-				}
-			}
-		};
-
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
-	/**
-	 * 
-	 *
-	 * @throws NotLoggedInException 
-	 * @since 3.0.5.3
-	 */
-	public static void getInvites()
-		throws NotLoggedInException {
-
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID_INVITE,
-				OP_GETINVITES, new Object[0], 1000);
-		message.setRequiresAuthorization(true, false);
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-
-			public void replyReceived(
-					PlatformMessage message,
-					String replyType,
-					Map reply) {
-				if (!replyType.equals(PlatformMessenger.REPLY_RESULT)) {
-					return;
-				}
-
-				List invitations = MapUtils.getMapList(reply, "invitations",
-						Collections.EMPTY_LIST);
-				
-				VuzeActivitiesEntry[] allEntries = VuzeActivitiesManager.getAllEntries();
-				List existingInvites = new ArrayList();
-				for (int i = 0; i < allEntries.length; i++) {
-					VuzeActivitiesEntry entry = allEntries[i];
-					if (entry instanceof VuzeActivitiesEntryBuddyRequest) {
-						VuzeActivitiesEntryBuddyRequest inviteEntry = (VuzeActivitiesEntryBuddyRequest) entry;
-						if (inviteEntry.getBuddy() != null) {
-							existingInvites.add(entry);
-						}
-					}
-				}
-
-				VuzeActivitiesEntry[] entries = (VuzeActivitiesEntry[]) existingInvites.toArray(new VuzeActivitiesEntry[0]);
-				VuzeActivitiesManager.removeEntries(entries, true);
-
-				if (invitations.size() == 0) {
-					return;
-				}
-
-				for (Iterator iter = invitations.iterator(); iter.hasNext();) {
-					Map mapInvitation = (Map) iter.next();
-
-					Map mapBuddy = MapUtils.getMapMap(mapInvitation, "buddy-info",
-							Collections.EMPTY_MAP);
-					long addedOn = SystemTime.getOffsetTime(MapUtils.getMapLong(mapInvitation,
-							"added-secs-ago", 0) * -1000);
-
-					String inviteCode = MapUtils.getMapString(mapInvitation, "code", null);
-					String acceptURL = MapUtils.getMapString(mapInvitation, "accept-url",
-							null);
-					long attempNumber = MapUtils.getMapLong(mapInvitation, "number", 0);
-
-					if (mapBuddy.isEmpty() || inviteCode == null || acceptURL == null) {
-						continue;
-					}
-					
-					VuzeActivitiesEntryBuddyRequest existingEntry = null;
-					for (Iterator iter2 = existingInvites.iterator(); iter2.hasNext();) {
-						VuzeActivitiesEntryBuddyRequest entry = (VuzeActivitiesEntryBuddyRequest) iter2.next();
-						if (inviteCode.equals(entry.getBuddy().getCode())) {
-							existingEntry = entry;
-							break;
-						}
-					}
-
-					VuzeBuddy futureBuddy = VuzeBuddyManager.createPotentialBuddy(null);
-					String loginID = MapUtils.getMapString(mapBuddy, "login-id", null);
-
-					VuzeBuddy existingBuddy = VuzeBuddyManager.getBuddyByLoginID(loginID);
-					if (existingBuddy != null) {
-						continue;
-					}
-
-					futureBuddy.loadFromMap(mapBuddy);
-					futureBuddy.setCode(inviteCode);
-					
-					if (existingEntry != null) {
-						existingEntry.init(futureBuddy, acceptURL, attempNumber);
-					} else {
-						existingEntry = new VuzeActivitiesEntryBuddyRequest();
-						existingEntry.init(futureBuddy, acceptURL, attempNumber);
-					}
-					
-					existingEntry.setTimestamp(addedOn);
-					VuzeActivitiesManager.addEntries(new VuzeActivitiesEntry[] {
-						existingEntry
-					});
-				}
-
-				//VuzeActivitiesEntry[] entries = (VuzeActivitiesEntry[]) existingInvites.toArray(new VuzeActivitiesEntry[existingInvites.size()]);
-				//VuzeActivitiesManager.removeEntries(entries);
-			}
-
-			public void messageSent(
-					PlatformMessage message) {
-			}
-		};
-
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
-	public static void getNumPendingInvites() {
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID_INVITE,
-				OP_COUNTINVITES, new Object[0], 1000);
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-
-			public void replyReceived(
-					PlatformMessage message,
-					String replyType,
-					Map reply) {
-
-				int count = MapUtils.getMapInt(reply, "count", 0);
-
-				// TODO fire off listener
-			}
-
-			public void messageSent(
-					PlatformMessage message) {
-			}
-		};
-
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
-	public static void invite(
-			String loginID,
-			String userMessage)
-		throws NotLoggedInException {
-
-		Map parameters = new HashMap();
-		parameters.put("message", userMessage);
-
-		List invitations = new ArrayList();
-		Map invitation = new HashMap();
-		parameters.put("invitations", invitations);
-		invitation.put("type", "username");
-		invitation.put("value", loginID);
-		invitations.add(invitation);
-
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID_INVITE,
-				OP_INVITE, parameters, 1000);
-		message.setRequiresAuthorization(true, false);
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-
-			public void replyReceived(
-					PlatformMessage message,
-					String replyType,
-					Map reply) {
-			}
-
-			public void messageSent(
-					PlatformMessage message) {
-			}
-		};
-
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
-	/**
-	 * @param buddy
-	 * @param login 
-	 * @throws NotLoggedInException 
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void remove(
-			final VuzeBuddy buddy,
-			boolean login)
-		throws NotLoggedInException {
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID_BUDDY,
-				OP_REMOVEBUDDY, new Object[] {
-					"username",
-					buddy.getLoginID()
-				}, 1000);
-		message.setRequiresAuthorization(true, login);
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-
-			public void replyReceived(
-					PlatformMessage message,
-					String replyType,
-					Map reply) {
-				VuzeBuddyManager.log("removal of " + buddy.getLoginID()
-						+ " from webapp: " + replyType);
-			}
-
-			public void messageSent(
-					PlatformMessage message) {
-			}
-		};
-
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
-	/**
-	 * 
-	 * @param referer Where share started from
-	 * @param hash hash of Vuze content being shared
-	 *
-	 * @since 3.0.5.3
-	 */
-	public static void startShare(String referer, String hash) {
-		boolean loggedIn = LoginInfoManager.getInstance().isLoggedIn();
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID_BUDDY,
-				OP_STARTSHARE, new Object[] {
-					"referer",
-					referer,
-					"logged-in",
-					new Boolean(loggedIn),
-					"torrent-hash",
-					hash
-				}, 1000);
-		if (loggedIn) {
-			try {
-				message.setRequiresAuthorization(true, false);
-			} catch (NotLoggedInException e) {
-				Debug.out(e);
-			}
-		}
-
-		PlatformMessenger.queueMessage(message, null);
-	}
-
-	public static long getLastSyncCheck() {
-		return lastSyncCheck;
-	}
-}
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformConfigMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformConfigMessenger.java
index 0aa955e..6bcad02 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformConfigMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformConfigMessenger.java
@@ -47,14 +47,14 @@ public class PlatformConfigMessenger
 {
 	public static final String LISTENER_ID = "config";
 
+	private static boolean allowSendDeviceList = false;
+
 	private static int iRPCVersion = 0;
 
 	private static String playAfterURL = null;
 
 	private static boolean sendStats = true;
 
-	protected static long buddySyncOnShareMinTime;
-
 	private static boolean doUrlQOS = false;
 	
 	private static boolean platformLoginComplete = false;
@@ -93,7 +93,6 @@ public class PlatformConfigMessenger
 		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID,
 				"login", params, maxDelayMS);
 		message.setContentNetworkID(contentNetworkID);
-		message.setRequiresAuthorizationNoCheck();
 
 		PlatformMessengerListener listener = new PlatformMessengerListener() {
 
@@ -102,6 +101,10 @@ public class PlatformConfigMessenger
 				if (reply == null) {
 					return;
 				}
+				
+				boolean allowMulti = MapUtils.getMapBoolean(reply, "allow-multi-rpc",
+						PlatformMessenger.getAllowMulti());
+				PlatformMessenger.setAllowMulti(allowMulti);
 
 				try {
 					List listURLs = (List) MapUtils.getMapObject(reply, "url-whitelist",
@@ -149,13 +152,13 @@ public class PlatformConfigMessenger
 				}
 				
 				try {
-					sendStats = MapUtils.getMapBoolean(reply, "send-stats", true);
+					sendStats = MapUtils.getMapBoolean(reply, "send-stats", false);
 					doUrlQOS = MapUtils.getMapBoolean(reply, "do-url-qos", false);
+					allowSendDeviceList = MapUtils.getMapBoolean(reply, "send-device-list", false);
 				} catch (Exception e) {
 				}
 				
-				buddySyncOnShareMinTime = MapUtils.getMapLong(reply, "buddy-sync-on-share-min-time-secs", 60000);
-
+				
 				try {
   				iRPCVersion = MapUtils.getMapInt(reply, "rpc-version", 0);
   				playAfterURL = (String) MapUtils.getMapString(reply,
@@ -164,11 +167,6 @@ public class PlatformConfigMessenger
 					Debug.out(e);
 				}
 				
-				Map mapUserInfo = MapUtils.getMapMap(reply, "user-info", null);
-				if (mapUserInfo != null) {
-					LoginInfoManager.getInstance().setUserInfo(mapUserInfo);
-				}
-				
 				platformLoginComplete = true;
 				Object[] listeners = platformLoginCompleteListeners.toArray();
 				platformLoginCompleteListeners = Collections.EMPTY_LIST;
@@ -237,14 +235,6 @@ public class PlatformConfigMessenger
 		return sendStats;
 	}
 
-	public static long getBuddySyncOnShareMinTimeSecs() {
-		return buddySyncOnShareMinTime;
-	}
-
-	public static void setBuddySyncOnShareMinTimeSecs(long buddySyncOnShareMinTime) {
-		PlatformConfigMessenger.buddySyncOnShareMinTime = buddySyncOnShareMinTime;
-	}
-
 	/**
 	 * @return
 	 *
@@ -276,4 +266,9 @@ public class PlatformConfigMessenger
 	public static interface PlatformLoginCompleteListener {
 		public void platformLoginComplete();
 	}
+
+
+	public static boolean allowSendDeviceList() {
+		return allowSendDeviceList;
+	}
 }
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformContentNetworkMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformContentNetworkMessenger.java
index cf487ee..e0fe3b7 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformContentNetworkMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformContentNetworkMessenger.java
@@ -47,6 +47,10 @@ PlatformContentNetworkMessenger
 	
 		throws PlatformMessengerException
 	{
+		if (true) {
+			return new ArrayList<contentNetworkDetails>(0);
+		}
+
 		JSONObject parameters = new JSONObject();
 		
 		parameters.put( "azver", Constants.AZUREUS_VERSION );
@@ -73,6 +77,11 @@ PlatformContentNetworkMessenger
 	public static void 
 	listNetworksAync(final listNetworksListener l, int maxDelayMS)
 	{
+		if (l != null) {
+			l.networkListReturned(new ArrayList<contentNetworkDetails>(0));
+			return;
+		}
+
 		JSONObject parameters = new JSONObject();
 
 		parameters.put("azver", Constants.AZUREUS_VERSION);
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformDCAdManager.java b/com/aelitis/azureus/core/messenger/config/PlatformDCAdManager.java
deleted file mode 100644
index 895d60f..0000000
--- a/com/aelitis/azureus/core/messenger/config/PlatformDCAdManager.java
+++ /dev/null
@@ -1,535 +0,0 @@
-package com.aelitis.azureus.core.messenger.config;
-
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrentException;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
-import org.bouncycastle.util.encoders.Base64;
-
-import java.util.*;
-import java.io.File;
-import java.io.IOException;
-
-import com.aelitis.azureus.util.*;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.core.messenger.PlatformMessage;
-import com.aelitis.azureus.core.messenger.PlatformMessenger;
-import com.aelitis.azureus.core.messenger.PlatformMessengerListener;
-
-/**
- * Created on Feb 8, 2008
- * Created by Alan Snyder
- * Copyright (C) 2007 Aelitis, All Rights Reserved.
- * <p/>
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * <p/>
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-
-public class PlatformDCAdManager
-{
-	// one week timeout for unsent impressions
-	private static final int UNSENT_TIMEOUT = 1000 * 3600 * 24 * 7;
-	public static String RPC_LISTENER_ID = "asxads";
-
-    public static String OP_GETADVERT = "get-advert";
-    public static String OP_SAVEIMPRESSIONS = "save-impressions";
-	public static List unsentImpressions = new ArrayList();
-	public static AEMonitor mon_unsentImpressions = new AEMonitor(
-			"unsavedImpressions");
-	public static boolean DEBUG_ADS = false;
-	private static int RESEND_DELAY = 1000 * 60 * 10; // 10 min
-	private static TimerEvent resendEvent;
-
-
-    /**
-     *  Create the call to the web-servers, and handle the response.
-     * @param adEnabledDownload - DownloadManager of content.
-     * @param maxDelayMS - Time to wait for the response.
-     * @param replyListener  - Needed by the PlatformManagerListener
-     */
-    public static void getAdvert(final DownloadManager adEnabledDownload,
-                                 long maxDelayMS,
-                                 final GetAdvertDataReplyListener replyListener)
-    {
-        debug("enter - PlatformDCDdManager.getAdvert");
-
-		//prepare the parameters to send
-        String contentHash="";
-        TOTorrent torrent = adEnabledDownload.getTorrent();
-        try{
-            contentHash = torrent.getHashWrapper().toBase32String();
-        }catch(TOTorrentException te){
-            debug("Failed to get currentHash",te);
-            te.printStackTrace();
-        }
-
-        
-        List contentList = new ArrayList();
-        //currently a list incase future calls will send multiple content.
-        contentList.add(contentHash);
-
-        List adList = getExistingAds();
-
-        //send
-        Map params = new HashMap();
-        params.put("hashes",contentList);
-        params.put("ads",adList);
-        PlatformMessage message = new PlatformMessage("AZMSG",RPC_LISTENER_ID,OP_GETADVERT,params, maxDelayMS);
-        message.setContentNetworkID(PlatformTorrentUtils.getContentNetworkID(torrent));
-
-		//create a default azpd file.
-		if( !azpdFileFound(message) ){
-			File f = determineAzpdFileName(message);
-			saveTempAzpdFile(f);
-		}
-
-
-		//deal with response.
-    PlatformMessengerListener l = new PlatformMessengerListener(){
-
-                public void messageSent(PlatformMessage message) {
-                    debug("getAdvert - messageSent");
-                    if (replyListener != null) {
-                        replyListener.messageSent();
-                    }
-                }//messageSent
-
-			public void replyReceived(PlatformMessage message, String replyType,
-					Map reply) {
-				boolean success = false;
-				try {
-					debug("getAdvert - replyReceived");
-					debug(replyType, message, reply);
-
-					//Deserialise and then download the torrent file.
-					if (reply != null) {
-						List adTorrents = new ArrayList();
-						List torrentsList = (List) reply.get("torrents");
-						if (torrentsList != null) {
-							for (int i = 0; i < torrentsList.size(); i++) {
-								byte[] torrentBEncoded = Base64.decode((String) torrentsList.get(i));
-								try {
-									TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedByteArray(torrentBEncoded);
-									adTorrents.add(torrent);
-								} catch (TOTorrentException e) {
-									Debug.out("PlatformDCAdManager.getAdvert - replyRecieved: "
-											+ e);
-								}
-							}
-						}
-
-						Map webParams = saveResponseToAzpdFile(reply, message);
-						DCAdManager.addParmasToDownloadManager(adEnabledDownload, webParams);
-
-						success = true;
-						if (replyListener != null) {
-							replyListener.adsReceived(adTorrents, webParams);
-						}
-					}
-				} catch (Exception e) {
-					Debug.out(e);
-				}
-
-				if (!success && replyListener != null) {
-					replyListener.replyReceived(replyType, reply);
-				}
-			}//replyReceived
-		};//class PlatformMessengerListener
-
-		if (maxDelayMS == 0) {
-			PlatformMessenger.pushMessageNow(message, l);
-		} else {
-			PlatformMessenger.queueMessage(message, l);
-		}
-
-		debug("leave - PlatformDCDdManager.getAdvert");
-	}//getAdvert
-
-	/**
-	 * create a temporary azpd file.
-	 * @param azpdFile
-	 */
-	private static void saveTempAzpdFile(File azpdFile){
-
-		String content = getTempAzpdTemplate();
-		AzpdFileAccess.writeAzpdFile(azpdFile,content);
-
-		debug( "temp data=_"+content+"_  to azpd file="+azpdFile.getAbsolutePath() );
-	}
-
-	/**
-	 * Template for a default azpd file. 
-	 * @return - template file.
-	 */
-	private static String getTempAzpdTemplate(){
-		//ToDo: Should be updateable configuration.
-		return "{\"ad_hash\":[],\"playlist\":\"<ASX version=\\\"3.0\\\">\\n<ENTRY ClientSkip=\\\"yes\\\">\\n<TITLE>" +
-				"Default<\\/TITLE>\\n<PARAM NAME=\\\"Prebuffer\\\" VALUE=\\\"true\\\"\\/>\\n" +
-				"<REF HREF=\\\"<##-CONTENT-PATH-##>\\\"\\/>\\n<\\/ENTRY>\\n<\\/ASX>\"}";
-	}
-
-
-	/**
-	 * Save the replay to the azpd file.
-	 * @param reply -
-	 * @param message -
-	 * @return - Map with params.
-	 */
-	private static Map saveResponseToAzpdFile(Map reply, PlatformMessage message) {
-        //What we might want to do here is remove "torrents" from the Map reply and then save the
-        //entire result.
-        Map saveToFile = new HashMap();
-        saveToFile.putAll(reply);
-        saveToFile.remove("torrents");
-
-		//Did we have an error? like when off-line. A "Thowable" param in map is an indication.
-		if( saveToFile.get("Throwable")!=null ){
-			return saveDefaultResponseToAzpdFile(message);
-		}
-
-		long currTime = System.currentTimeMillis();
-		saveToFile.put( AzpdFileAccess.PARAM_CREATE_TIME, ""+currTime );
-
-		//if the web doesn't specify an expire time, the make it one week.
-		if( saveToFile.get( AzpdFileAccess.PARAM_EXPIRE_TIME )==null ){
-			long expireTime = currTime + 1000 * 60 * 60 * 24 * 7;//one week;
-			saveToFile.put( AzpdFileAccess.PARAM_EXPIRE_TIME, ""+expireTime );
-		}
-
-		String s = JSONUtils.encodeToJSON(saveToFile);
-		File file = determineAzpdFileName(message);
-
-		AzpdFileAccess.writeAzpdFile(file,s);
-
-		debug( "data=_"+s+"_  to azpd file="+file.getAbsolutePath() );
-        
-        return JSONUtils.decodeJSON(s);
-    }
-
-
-	/**
-	 * When offline of another error occurs. Save the default template to play only the content.
-	 * It should expire immediately, to replace it on restart.
-	 * @param message -
-	 * @return -
-	 */
-	private static Map saveDefaultResponseToAzpdFile(PlatformMessage message){
-		File azpdFile = determineAzpdFileName(message);
-		saveTempAzpdFile(azpdFile);
-		debug("using content-only template due to error.");
-		try{
-			Map webParams = AzpdFileAccess.readAzpdFileToMap(azpdFile);
-			webParams.put( AzpdFileAccess.PARAM_IS_OFFLINE, "true" );
-		}catch(IOException ioe){
-			ioe.printStackTrace();
-		}
-		return new HashMap();
-	}
-
-	/**
-	 * Based on the hash determine the Azpd file name.
-	 * @param message -
-	 * @return File - azpd file.
-	 */
-	private static File determineAzpdFileName(PlatformMessage message) {
-		File azpdFile = AzpdFileAccess.getAzpdDir();
-
-		//Get the content hash from the message.
-		String azpdFileNameBase = "no_file";
-		Map requestParamMap = message.getParameters();
-		if( requestParamMap!=null ){
-			List contentList = (List) requestParamMap.get("hashes");
-			if( contentList!=null ){
-				azpdFileNameBase = (String) contentList.get(0);
-			}
-		}
-
-		File file = new File(azpdFile, azpdFileNameBase+".azpd" );
-		return file;
-	}
-
-	/**
-	 * True if the azpd file for content exists.
-	 * @param message - to get the hash
-	 * @return boolean - true if it exists.
-	 */
-	private static boolean azpdFileFound(PlatformMessage message){
-		File f = determineAzpdFileName(message);
-		return f.exists();
-	}
-
-
-	private static List getExistingAds() {
-        DownloadManager[] existingAds = DCAdManager.getInstance().getAds(true);
-        List adList = new ArrayList();
-        for (int i = 0; i < existingAds.length; i++) {
-            DownloadManager dm = existingAds[i];
-
-            try {
-                TOTorrent torrent = dm.getTorrent();
-                String hash = torrent.getHashWrapper().toBase32String();
-                String adid = PlatformTorrentUtils.getAdId(torrent);//ToDo: Is AdId in torrent file no longer needed?
-
-                Map mapAd = new HashMap();
-                mapAd.put("hash", hash);
-
-                adList.add(mapAd);
-            } catch (TOTorrentException te) {
-                debug("Failed while reading existing ads",te);
-                te.printStackTrace();
-            }
-        }
-        return adList;
-    }
-
-
-    public static interface GetAdvertDataReplyListener{
-        public void messageSent();
-
-        public void adsReceived(List torrents, Map webParams);
-
-        public void replyReceived(String replyType, Map mapHashes);
-    }
-
-
-    /**
-     * Send the impression information.
-     * @param impressionUrl -
-     * @param viewedOn -
-     * @param contentHash -
-     * @param torrentHash -
-     * @param adHash      -
-     * @param thirdPartyImpressionUrl Array of thirdparty impression urls encoded as a json array of strings. 
-     * @param maxDelayMS  -
-     */
-    public static void saveImpression(String impressionUrl, long viewedOn,
-            String contentHash, String torrentHash, String adHash, String thirdPartyImpressionUrl,
-            long maxDelayMS) {
-        // pass in contentHash instead of DownloadManager in case the user removed
-        // the DM (and we are retrying)
-        try {
-            Map ad = new HashMap();
-
-            ad.put("tracking-id", impressionUrl);
-            ad.put("viewed-on", new Long(viewedOn));
-            ad.put("content-hash", contentHash);
-            if (torrentHash != null) {
-                ad.put("torrent-hash", torrentHash);
-            }
-            if (adHash != null) {
-                ad.put("hash", adHash);
-            }
-            if( thirdPartyImpressionUrl != null ) {
-            	ad.put("thirdPartyImp", thirdPartyImpressionUrl);
-            }
-
-            try {
-                mon_unsentImpressions.enter();
-                unsentImpressions.add(ad);
-            } finally {
-                mon_unsentImpressions.exit();
-            }
-            saveUnsentImpressions();
-            sendUnsentImpressions(maxDelayMS);
-        } catch (Exception e) {
-            Debug.out(e);
-        }
-    }
-
-
-
-    //ToDo: rename to sendUnsavedImpressions
-    public static void sendUnsentImpressions(long maxDelayMS) {
-        // clear unsentImpressions.  If storing fails, we'll add them back in
-        List sendingImpressions;
-        try {
-            mon_unsentImpressions.enter();
-
-            sendingImpressions = unsentImpressions;
-            unsentImpressions = new ArrayList();
-            saveUnsentImpressions();
-        } finally {
-            mon_unsentImpressions.exit();
-        }
-
-        if (sendingImpressions.size() == 0) {
-            return;
-        }
-
-        final List fSendingImpressions = sendingImpressions;
-
-        Map ads = new HashMap();
-        ads.put("ads", fSendingImpressions);
-        ads.put("rpc-version", new Long(2));
-
-        try {
-            debug("sending " + fSendingImpressions.size() + " impressions");
-            PlatformMessage message = new PlatformMessage("AZMSG", RPC_LISTENER_ID,
-                    OP_SAVEIMPRESSIONS, ads, maxDelayMS);
-
-            PlatformMessenger.queueMessage(message, new PlatformMessengerListener() {
-                public void replyReceived(PlatformMessage message, String replyType,
-                        Map reply) {
-                    if (!replyType.equals(PlatformMessenger.REPLY_RESULT)) {
-                        debug("sending " + fSendingImpressions + " impressions failed. "
-                                + reply);
-                        try {
-                            mon_unsentImpressions.enter();
-
-                            unsentImpressions.addAll(fSendingImpressions);
-
-                            _setupResendTimer();
-                        } finally {
-                            mon_unsentImpressions.exit();
-                        }
-                        saveUnsentImpressions();
-                        return;
-                    }
-                    // TODO: check result to see which ones succeeded
-                    debug("sending " + fSendingImpressions.size()
-                            + " impressions completed");
-                }
-
-                public void messageSent(PlatformMessage message) {
-                }
-
-            });
-        } catch (Exception e) {
-            Debug.out(e);
-        }
-    }
-
-    /**
-     *
-     *
-     * @since 3.0.1.5
-     */
-    protected static void _setupResendTimer() {
-        if (resendEvent != null) {
-            resendEvent.cancel();
-            resendEvent = null;
-        }
-        resendEvent = SimpleTimer.addEvent("resender",
-                SystemTime.getOffsetTime(RESEND_DELAY), new TimerEventPerformer() {
-                    public void perform(TimerEvent event) {
-                        debug("resend impressions triggered");
-                        sendUnsentImpressions(5000);
-                    }
-                });
-    }
-
-    /**
-     *
-     *
-     * @since 3.0.1.5
-     */
-    private static void saveUnsentImpressions() {
-        try {
-            mon_unsentImpressions.enter();
-
-            Map map = new HashMap();
-            map.put("unsent", unsentImpressions);
-            FileUtil.writeResilientConfigFile("unsentdata.config", map);
-        } finally {
-            mon_unsentImpressions.exit();
-        }
-    }
-
-    public static void loadUnsentImpressions() {
-        try {
-            mon_unsentImpressions.enter();
-
-            Map map = BDecoder.decodeStrings(FileUtil.readResilientConfigFile("unsentdata.config"));
-            Object value = map.get("unsent");
-            if (value instanceof List) {
-                unsentImpressions = (List) value;
-                for (Iterator iter = unsentImpressions.iterator(); iter.hasNext();) {
-                    long viewedOn = 0;
-                    Map ad = (Map) iter.next();
-                    try {
-                        if (ad.containsKey("viewed-on")) {
-                            viewedOn = ((Long) ad.get("viewed-on")).longValue();
-                        }
-                    } catch (Exception e) {
-                    }
-
-                    if (SystemTime.getCurrentTime() - viewedOn > UNSENT_TIMEOUT) {
-                        iter.remove();
-                        debug("timing out impression " + ad.get("tracking-id"));
-                    }
-                }
-            } else {
-                unsentImpressions.clear();
-            }
-        } finally {
-            mon_unsentImpressions.exit();
-        }
-    }
-
-    public static void debug(String string) {
-        debug(string, null);
-    }
-
-    /**
-     * @param string -
-     * @param e -
-     *
-     * @since 3.0.1.7
-     */
-    public static void debug(String string, Throwable e) {
-        try {
-            AEDiagnosticsLogger diag_logger = AEDiagnostics.getLogger("v3.ads");
-            diag_logger.log(string);
-
-            if (e != null) {
-                diag_logger.log(e);
-                Debug.out(string, e);
-            }
-            if (ConstantsVuze.DIAG_TO_STDOUT || DEBUG_ADS) {
-                System.out.println(Thread.currentThread().getName() + "|ADS|"
-                        + System.currentTimeMillis() + "] " + string);
-                if (e != null) {
-                    e.printStackTrace();
-                }
-            }
-        } catch (Throwable t) {
-            // ignore
-        }
-    }
-
-    /**
-     * Delete this problem some day.
-     * @param replyType -
-     * @param message -
-     * @param reply -
-     */
-    private static void debug(String replyType, PlatformMessage message, Map reply) {
-        debug( "------ PlatformDCAdManager.getAdvert()  PlatformMessageListener.reply()  ------" );
-        debug( replyType );
-        debug( message.toString() );
-
-        if(reply!=null){
-            String wOrd = (String) reply.get("web_ord");
-            String wAdId = (String) reply.get("web_ad_id");
-            String playlist = (String) reply.get("playlist");
-            debug("web_ord: "+wOrd);
-            debug("web_ad_id: "+wAdId);
-            debug("playlist: "+playlist);
-        }
-        debug( "-------------------------------------------------------------------------------" );
-    }
-
-}
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformDevicesMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformDevicesMessenger.java
index d3db47e..b3c2275 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformDevicesMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformDevicesMessenger.java
@@ -270,6 +270,9 @@ public class PlatformDevicesMessenger
 	}
 
 	private static void sendDeviceList(Device[] devices) {
+		if (!PlatformConfigMessenger.allowSendDeviceList()) {
+			return;
+		}
 		List<String> listRenderers = new ArrayList<String>(devices.length);
 		for (Device dev : devices) {
 			if (dev.getType() == Device.DT_MEDIA_RENDERER) {
@@ -277,6 +280,9 @@ public class PlatformDevicesMessenger
 			}
 		}
 
+		if (listRenderers.size() == 0) {
+			return;
+		}
 		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID,
 				OP_REPORT_DEVICES, new Object[] {
 					"renderers",
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformKeyExchangeMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformKeyExchangeMessenger.java
deleted file mode 100644
index ee69881..0000000
--- a/com/aelitis/azureus/core/messenger/config/PlatformKeyExchangeMessenger.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * Created on Apr 24, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.core.messenger.config;
-
-import java.util.Map;
-
-import org.gudy.azureus2.core3.util.Debug;
-
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.crypto.VuzeCryptoException;
-import com.aelitis.azureus.core.crypto.VuzeCryptoManager;
-import com.aelitis.azureus.core.messenger.PlatformMessage;
-import com.aelitis.azureus.core.messenger.PlatformMessenger;
-import com.aelitis.azureus.core.messenger.PlatformMessengerListener;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.util.ConstantsVuze;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author TuxPaper
- * @created Apr 24, 2008
- *
- */
-public class PlatformKeyExchangeMessenger
-{
-	public static final String LISTENER_ID = "exchange";
-
-	public static final String PREFIX = "key";
-
-	public static String OP_GETPASSWORD = "getPassword";
-
-	public static String OP_SETPUBLICKEY = "setPublicKey";
-
-	public static void getPassword(
-			final platformPasswordListener l)
-		throws NotLoggedInException {
-		if (!System.getProperty("crypto.skip", "").equals("")) {
-			VuzeCryptoManager.getSingleton().setPassword(System.getProperty("crypto.skip"));
-			if (l != null) {
-				l.passwordRetrieved();
-			}
-			return;
-		}
-		PlatformMessage message = new PlatformMessage(PREFIX, LISTENER_ID,
-				OP_GETPASSWORD, new Object[0], 1000);
-		message.setRequiresAuthorization(true, false);
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-
-			public void replyReceived(
-					PlatformMessage message,
-					String replyType,
-					Map reply) {
-				if (!replyType.equals(PlatformMessenger.REPLY_RESULT)) {
-					l.passwordRetrievalFailed();
-					return;
-				}
-
-				String pw = MapUtils.getMapString(reply, "password", null);
-				if (pw != null && pw.length() > 0) {
-					// for session
-					VuzeBuddyManager.log("Got PW from webapp");
-					VuzeCryptoManager.getSingleton().setPassword(pw);
-					if (l != null) {
-						l.passwordRetrieved();
-					}
-					return;
-				}
-				l.passwordRetrievalFailed();
-			}
-
-			public void messageSent(
-					PlatformMessage message) {
-			}
-		};
-
-		// we want to do this immediately, before any other queued items
-		PlatformMessenger.pushMessageNow(message, listener);
-	}
-
-	public static void setPublicKey()
-		throws NotLoggedInException {
-		final String myPK;
-		try {
-			myPK = VuzeCryptoManager.getSingleton().getPublicKey(null);
-		} catch (VuzeCryptoException e) {
-			Debug.out(e);
-			return;
-		}
-
-		PlatformMessage message = new PlatformMessage(PREFIX, LISTENER_ID,
-				OP_SETPUBLICKEY, new Object[] {
-					"azid",
-					ConstantsVuze.AZID,
-					"publicKey",
-					myPK
-				}, 1000);
-		message.setRequiresAuthorization(true, false);
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-
-			public void replyReceived(
-					PlatformMessage message,
-					String replyType,
-					Map reply) {
-				VuzeBuddyManager.log("Webapp setPK: " + replyType);
-			}
-
-			public void messageSent(
-					PlatformMessage message) {
-			}
-		};
-		// we want to do this immediately, before any other queued items
-		PlatformMessenger.pushMessageNow(message, listener);
-	}
-
-	public static interface platformPasswordListener
-	{
-		public void passwordRetrieved();
-		public void passwordRetrievalFailed();
-	}
-}
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformRatingMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformRatingMessenger.java
deleted file mode 100644
index 326e7c3..0000000
--- a/com/aelitis/azureus/core/messenger/config/PlatformRatingMessenger.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/**
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package com.aelitis.azureus.core.messenger.config;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.torrent.TOTorrentException;
-import org.gudy.azureus2.core3.util.*;
-
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.messenger.PlatformMessage;
-import com.aelitis.azureus.core.messenger.PlatformMessenger;
-import com.aelitis.azureus.core.messenger.PlatformMessengerListener;
-import com.aelitis.azureus.core.torrent.*;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author TuxPaper
- * @created Oct 4, 2006
- *
- */
-public class PlatformRatingMessenger
-{
-	private static final int GLOBAL_DEF_EXPIRY_MINS = 48 * 60;
-
-	private static final long GLOBAL_RETRY_UPDATERATING = 10 * 60 * 1000;
-
-	public static final String LISTENER_ID = "rating";
-
-	public static final String OP_GET = "get";
-
-	public static final String OP_SET = "set";
-
-	public static final String RATE_TYPE_CONTENT = "content";
-
-	public static final ArrayList listeners = new ArrayList();
-
-	private static final int BREAK_GGR = 1000;
-
-	private static boolean delayGlobalRatingUpdate = true;
-
-	private static List<TOTorrent> delayedGlobalRatingTorrents;
-	
-	private static AEMonitor mon_DelayedGlobalRatingTorrents = new AEMonitor("delayedGlobalRatingTorrents");
-
-	public static void getUserRating(long contentNetworkID, String[] rateTypes,
-			final String[] torrentHashes, long maxDelayMS) {
-
-		if (contentNetworkID <= 0) {
-			return;
-		}
-
-		PlatformMessage message = new PlatformMessage("AZMSG", "rating",
-				"get-user", new Object[] {
-					"rating-type",
-					rateTypes,
-					"torrent-hash",
-					torrentHashes,
-				}, maxDelayMS);
-		message.setContentNetworkID(contentNetworkID);
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-			public void messageSent(PlatformMessage message) {
-			}
-
-			public void replyReceived(PlatformMessage message, String replyType,
-					Map reply) {
-				// must create GetRatingReply object even if there's no replyListener
-				// as class creation may cause other listener triggers
-				RatingInfoList ratingReply = new PlatformRatingInfoList(reply);
-
-				AzureusCore core = AzureusCoreFactory.getSingleton();
-				for (int i = 0; i < torrentHashes.length; i++) {
-					String hash = torrentHashes[i];
-					long value = ratingReply.getRatingValue(hash,
-							PlatformRatingMessenger.RATE_TYPE_CONTENT);
-					if (value >= -1) {
-						DownloadManager dm = core.getGlobalManager().getDownloadManager(
-								new HashWrapper(Base32.decode(hash)));
-						if (dm != null && dm.getTorrent() != null) {
-							if (PlatformRatingMessenger.ratingSucceeded(reply)) {
-								PlatformTorrentUtils.setUserRating(dm.getTorrent(), (int) value);
-							} else {
-								PlatformTorrentUtils.setUserRating(dm.getTorrent(), -1);
-							}
-						}
-					}
-				}
-			}
-		};
-
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
-	private static void getGlobalRating(String[] rateTypes,
-			String[] torrentHashes, long maxDelayMS,
-			final GetRatingReplyListener replyListener) {
-
-		if (torrentHashes.length > BREAK_GGR) {
-			int pos = 0;
-			int len;
-
-			do {
-				len = torrentHashes.length - pos;
-				if (len > BREAK_GGR) {
-					len = BREAK_GGR;
-				}
-
-				String[] hashes = new String[len];
-				System.arraycopy(torrentHashes, pos, hashes, 0, len);
-				getGlobalRating(rateTypes, hashes, maxDelayMS, replyListener);
-
-				pos += len;
-			} while (len == BREAK_GGR);
-
-			return;
-		}
-		
-		PlatformMessage message = new PlatformMessage("AZMSG", "rating",
-				"get-global", new Object[] {
-					"rating-type",
-					rateTypes,
-					"torrent-hash",
-					torrentHashes,
-				}, maxDelayMS);
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-			public void messageSent(PlatformMessage message) {
-				replyListener.messageSent();
-			}
-
-			public void replyReceived(PlatformMessage message, String replyType,
-					Map reply) {
-				RatingInfoList ratingReply = new PlatformRatingInfoList(reply);
-				invokeUpdateListeners(ratingReply);
-				replyListener.replyReceived(replyType, ratingReply);
-			}
-		};
-
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
-	public static void setUserRating(final TOTorrent torrent, final int rating,
-			final boolean updateGlobalRatingAfter, long maxDelayMS,
-			final PlatformMessengerListener l) {
-
-		if (torrent == null) {
-			return;
-		}
-
-		String torrentHash = null;
-		try {
-			torrentHash = torrent.getHashWrapper().toBase32String();
-		} catch (TOTorrentException e) {
-		}
-		if (torrentHash == null) {
-			return;
-		}
-
-		final String fTorrentHash = torrentHash;
-
-		List array = new ArrayList();
-		array.add(PlatformMessage.parseParams(new Object[] {
-			"rating-type",
-			"content",
-			"rating-value",
-			new Integer(rating)
-		}));
-
-		PlatformMessage message = new PlatformMessage("AZMSG", "rating", "set",
-				new Object[] {
-					"torrent-hash",
-					torrentHash,
-					"ratings",
-					array
-				}, maxDelayMS);
-		message.setContentNetworkID(PlatformTorrentUtils.getContentNetworkID(torrent));
-
-		final int oldRating = PlatformTorrentUtils.getUserRating(torrent);
-		final RatingInfoList ratingReply = new SingleUserRatingInfo(torrent);
-
-		PlatformTorrentUtils.setUserRating(torrent, -2);
-
-		PlatformMessenger.queueMessage(message, new PlatformMessengerListener() {
-			// @see com.aelitis.azureus.core.messenger.PlatformMessengerListener#messageSent(com.aelitis.azureus.core.messenger.PlatformMessage)
-
-			public void messageSent(PlatformMessage message) {
-				if (l != null) {
-					l.messageSent(message);
-				}
-			}
-
-			// @see com.aelitis.azureus.core.messenger.PlatformMessengerListener#replyReceived(com.aelitis.azureus.core.messenger.PlatformMessage, java.lang.String, java.lang.Object)
-			public void replyReceived(PlatformMessage message, String replyType,
-					Map reply) {
-				if (PlatformRatingMessenger.ratingSucceeded(reply)) {
-					PlatformTorrentUtils.setUserRating(torrent, (int) rating);
-					if (updateGlobalRatingAfter) {
-						updateGlobalRating(torrent, 2000);
-					}
-				} else {
-					PlatformTorrentUtils.setUserRating(torrent,
-							oldRating == GlobalRatingUtils.RATING_WAITING
-									? GlobalRatingUtils.RATING_NONE : oldRating);
-				}
-				if (l != null) {
-					l.replyReceived(message, replyType, reply);
-				}
-			}
-		});
-	}
-
-	public static boolean ratingSucceeded(Map map) {
-		String message = MapUtils.getMapString(map, "message", null);
-
-		if (message != null) {
-			return message.equals("Ok");
-		}
-
-		return MapUtils.getMapBoolean(map, "success", false);
-	}
-
-	private static abstract class GetRatingReplyListener
-	{
-		public abstract void messageSent();
-
-		public abstract void replyReceived(String replyType, RatingInfoList reply);
-	}
-
-	public static void addListener(RatingUpdateListener2 l) {
-		if (!listeners.contains(l)) {
-			listeners.add(l);
-		}
-	}
-
-	public static void removeListener(RatingUpdateListener2 l) {
-		listeners.remove(l);
-	}
-
-	public static void addListener(RatingUpdateListener l) {
-		if (!listeners.contains(l)) {
-			listeners.add(l);
-		}
-	}
-
-	public static void removeListener(RatingUpdateListener l) {
-		listeners.remove(l);
-	}
-
-	public static void invokeUpdateListeners(RatingInfoList rating) {
-		Object[] listArray = listeners.toArray();
-		for (int i = 0; i < listArray.length; i++) {
-			try {
-  			if (listArray[i] instanceof RatingUpdateListener) {
-  				((RatingUpdateListener)listArray[i]).ratingUpdated(rating);
-  			} else if (listArray[i] instanceof RatingUpdateListener2) {
-  				((RatingUpdateListener2)listArray[i]).ratingUpdated(rating);
-  			}
-			} catch (Exception e) {
-				Debug.out(e);
-			}
-		}
-	}
-
-	public static void updateGlobalRating(TOTorrent[] _torrents, long maxDelayMS) {
-		if (_torrents == null) {
-			return;
-		}
-
-		mon_DelayedGlobalRatingTorrents.enter();
-		try {
-  		if (delayGlobalRatingUpdate) {
-  			if (delayedGlobalRatingTorrents == null) {
-  				delayedGlobalRatingTorrents = new ArrayList<TOTorrent>();
-  			}
-  			for (int i = 0; i < _torrents.length; i++) {
-  				if (!delayedGlobalRatingTorrents.contains(_torrents[i])) {
-  					delayedGlobalRatingTorrents.add(_torrents[i]);
-  				}
-  			}
-  			return;
-
-  		} else if (delayedGlobalRatingTorrents != null) {
-  			for (int i = 0; i < _torrents.length; i++) {
-  				if (!delayedGlobalRatingTorrents.contains(_torrents[i])) {
-  					delayedGlobalRatingTorrents.add(_torrents[i]);
-  				}
-  			}
-  			_torrents = delayedGlobalRatingTorrents.toArray(new TOTorrent[0]);
-  			delayedGlobalRatingTorrents.clear();
-  		}
-		} finally {
-			mon_DelayedGlobalRatingTorrents.exit();
-		}
-		
-		final TOTorrent[] torrents = _torrents;
-		
-		ArrayList hashes = new ArrayList(torrents.length);
-		for (TOTorrent torrent : torrents) {
-			if (torrent != null) {
-				try {
-					hashes.add(torrent.getHashWrapper().toBase32String());
-				} catch (TOTorrentException e) {
-				}
-			}
-		}
-		
-		if (hashes.size() == 0) {
-			return;
-		}
-		
-		final String[] hashesArray = (String[]) hashes.toArray(new String[hashes.size()]);
-
-		if (PlatformTorrentUtils.DEBUG_CACHING) {
-			PlatformTorrentUtils.log("v3.GR.caching: updateFromPlatform for "
-					+ hashes.size());
-		}
-		PlatformRatingMessenger.getGlobalRating(new String[] {
-			PlatformRatingMessenger.RATE_TYPE_CONTENT
-		}, hashesArray, 5000, new GetRatingReplyListener() {
-			public void replyReceived(String replyType, RatingInfoList reply) {
-				if (PlatformTorrentUtils.DEBUG_CACHING) {
-					PlatformTorrentUtils.log("v3.GR.caching: reply '" + replyType + "'");
-				}
-				if (replyType.equals(PlatformMessenger.REPLY_RESULT)) {
-					ArrayList hashes = new ArrayList(torrents.length);
-					for (TOTorrent torrent : torrents) {
-						String hash = null;
-						if (torrent != null) {
-							try {
-								hash = torrent.getHashWrapper().toBase32String();
-							} catch (TOTorrentException e) {
-							}
-						}
-						if (hash == null) {
-							continue;
-						}
-						String type = PlatformRatingMessenger.RATE_TYPE_CONTENT;
-						String rating = reply.getRatingString(hash, type);
-						String color = reply.getRatingColor(hash, type);
-						long count = reply.getRatingCount(hash, type);
-						long expireyMins = reply.getRatingExpireyMins(hash, type);
-
-						if (expireyMins <= 0) {
-							expireyMins = GLOBAL_DEF_EXPIRY_MINS;
-						}
-
-						long refreshOn = SystemTime.getCurrentTime()
-								+ (expireyMins * 60 * 1000L);
-
-						GlobalRatingUtils.setRating(torrent, rating, color, count,
-								refreshOn);
-					}
-				} else if (replyType.equals(PlatformMessenger.REPLY_EXCEPTION)) {
-					// try again in a bit
-					SimpleTimer.addEvent("Update MD Retry", SystemTime.getCurrentTime()
-							+ GLOBAL_RETRY_UPDATERATING, new TimerEventPerformer() {
-						public void perform(TimerEvent event) {
-							if (PlatformTorrentUtils.DEBUG_CACHING) {
-								PlatformTorrentUtils.log("v3.GR.caching: retrying..");
-							}
-							updateGlobalRating(torrents, 15000);
-						}
-					});
-
-				}
-			}
-
-			public void messageSent() {
-			}
-		});
-	}
-
-	public static void updateGlobalRating(TOTorrent torrent, long maxDelayMS) {
-		updateGlobalRating(new TOTorrent[] {
-			torrent
-		}, maxDelayMS);
-	}
-
-	// Old EMP needs this class
-	public static interface RatingUpdateListener
-	{
-		public void ratingUpdated(GetRatingReply rating);
-	}
-
-	// Old EMP needs this class
-	public static abstract class GetRatingReply
-	{
-		public abstract boolean hasHash(String hash);
-
-		public abstract long getRatingValue(String hash, String type);
-
-		public abstract long getRatingCount(String hash, String type);
-
-		public abstract String getRatingString(String hash, String type);
-
-		public abstract String getRatingColor(String hash, String type);
-
-		public abstract long getRatingExpireyMins(String hash, String type);
-	}
-
-	public static boolean isGlobalRatingUpdateDelayed() {
-		return delayGlobalRatingUpdate;
-	}
-
-	public static void setGlobalRatingUpdateDelayed(boolean delayGlobalRatingUpdate) {
-		if (PlatformRatingMessenger.delayGlobalRatingUpdate == delayGlobalRatingUpdate) {
-			return;
-		}
-		PlatformRatingMessenger.delayGlobalRatingUpdate = delayGlobalRatingUpdate;
-		if (!delayGlobalRatingUpdate) {
-			updateGlobalRating(new TOTorrent[0], 1000);
-		}
-	}
-}
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformRelayMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformRelayMessenger.java
deleted file mode 100644
index b19de4f..0000000
--- a/com/aelitis/azureus/core/messenger/config/PlatformRelayMessenger.java
+++ /dev/null
@@ -1,444 +0,0 @@
-/**
- * Created on Apr 17, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.core.messenger.config;
-
-import java.util.*;
-
-import org.gudy.azureus2.core3.util.*;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.crypto.VuzeCryptoException;
-import com.aelitis.azureus.core.crypto.VuzeCryptoManager;
-import com.aelitis.azureus.core.messenger.PlatformMessage;
-import com.aelitis.azureus.core.messenger.PlatformMessenger;
-import com.aelitis.azureus.core.messenger.PlatformMessengerListener;
-import com.aelitis.azureus.core.security.CryptoHandler;
-import com.aelitis.azureus.core.security.CryptoManagerFactory;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.plugins.net.buddy.*;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPlugin.cryptoResult;
-import com.aelitis.azureus.util.LoginInfoManager;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author TuxPaper
- * @created Apr 17, 2008
- *
- */
-public class PlatformRelayMessenger
-{
-	public static final String MSG_ID = "AZMSG";
-
-	public static final String LISTENER_ID = "relay";
-
-	public static final long DEFAULT_RECHECKIN_MINS = 30;
-
-	private static final long ERROR_RECHECKIN_MINS = 90;
-
-	private static final boolean TEST_ERRORACK = System.getProperty(
-			"relay.errack.test", "0").equals("1");
-
-	public static String OP_FETCH = "fetch";
-
-	public static String OP_PUT = "put";
-
-	public static String OP_ACK = "ack";
-
-	public static String OP_ERRORACK = "error_ack";
-
-	public static String OP_COUNT = "count";
-
-	public static List listeners = new ArrayList();
-
-	private static TimerEventPerformer relayCheckPerformer;
-
-	private static TimerEvent timerEvent;
-
-	private static long lastPendingCount = 0;
-
-	static {
-		relayCheckPerformer = new TimerEventPerformer() {
-			public void perform(TimerEvent event) {
-				relayCheck();
-			}
-		};
-	}
-
-	/**
-	 * Put a message on the relay server.
-	 * <p>
-	 * Note: There should be only one pk if your payload is encrypted or
-	 *       has a buddyMessage
-	 * 
-	 * @param pks
-	 * @param buddyMessage
-	 * @param maxDelayMS
-	 *
-	 * @since 3.0.5.3
-	 */
-
-	public static final void put(final BuddyPluginBuddyMessage buddyMessage,
-			long maxDelayMS, final putListener putListener) {
-		try {
-			// if ( true ) throw( new Exception( "bork bork" ));
-			final String myPK = VuzeCryptoManager.getSingleton().getPublicKey(
-					"RelayMessenger put");
-
-			BuddyPluginBuddy pluginBuddy = buddyMessage.getBuddy();
-
-			final String pk = pluginBuddy.getPublicKey();
-
-			byte[] encode = BEncoder.encode(buddyMessage.getRequest());
-
-			cryptoResult encryptResult = pluginBuddy.encrypt(encode);
-
-			final Map mapParameters = new HashMap();
-			mapParameters.put("sender_pk", myPK);
-			mapParameters.put("recipient_pk", pk);
-			mapParameters.put("payload", Base32.encode(encryptResult.getPayload()));
-			mapParameters.put("ack_hash", Base32.encode(encryptResult.getChallenge()));
-
-			PlatformMessage message = new PlatformMessage(MSG_ID, LISTENER_ID,
-					OP_PUT, mapParameters, maxDelayMS) {
-				// @see com.aelitis.azureus.core.messenger.PlatformMessage#toString()
-				public String toString() {
-					return "PlaformMessage {" + getSequenceNo() + ", " + getMessageID()
-							+ ", " + getListenerID() + ", " + getOperationID() + ", sender="
-							+ myPK + ", recipient=" + pk + ", ack_hash="
-							+ mapParameters.get("ack_hash") + "}";
-				}
-			};
-
-			PlatformMessengerListener listener = new PlatformMessengerListener() {
-				public void messageSent(PlatformMessage message) {
-				}
-
-				public void replyReceived(PlatformMessage message, String replyType,
-						Map reply) {
-					boolean ok = false;
-
-					try {
-						String replyMessage = MapUtils.getMapString(reply, "message", null);
-
-						if (replyMessage != null && replyMessage.equals("Ok")) {
-							// good
-							PlatformMessenger.debug("Relay: Ok to " + pk);
-
-							putListener.putOK(buddyMessage);
-
-							ok = true;
-
-						} else {
-							// bad
-							PlatformMessenger.debug("Relay: FAILED for " + pk);
-
-						}
-					} finally {
-
-						if (!ok) {
-
-							putListener.putFailed(buddyMessage, new Exception(
-									"Reply indicated failure: " + reply));
-						}
-					}
-				}
-
-			};
-
-			PlatformMessenger.queueMessage(message, listener);
-
-		} catch (Throwable e) {
-
-			putListener.putFailed(buddyMessage, e);
-		}
-	}
-
-	public static final void fetch(long maxDelayMS)
-			throws NotLoggedInException {
-		if (!LoginInfoManager.getInstance().isLoggedIn()
-				|| PlatformMessenger.isAuthorizedDelayed()) {
-			resetTimerEvent(DEFAULT_RECHECKIN_MINS);
-			throw new NotLoggedInException();
-		}
-
-		String myPK;
-		try {
-			myPK = VuzeCryptoManager.getSingleton().getPublicKey(null);
-		} catch (VuzeCryptoException e) {
-			resetTimerEvent(DEFAULT_RECHECKIN_MINS);
-			Debug.out(e);
-			return;
-		}
-
-		PlatformMessage message = new PlatformMessage(MSG_ID, LISTENER_ID,
-				OP_FETCH, new Object[] {
-					"pk",
-					myPK
-				}, maxDelayMS);
-
-		final BuddyPlugin buddyPlugin = VuzeBuddyManager.getBuddyPlugin();
-		if (buddyPlugin == null) {
-			resetTimerEvent(DEFAULT_RECHECKIN_MINS);
-			return;
-		}
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-
-			public void messageSent(PlatformMessage message) {
-			}
-
-			public void replyReceived(PlatformMessage message, String replyType,
-					Map reply) {
-				List list = (List) MapUtils.getMapObject(reply, "messages",
-						Collections.EMPTY_LIST, List.class);
-				long recheckInMins = MapUtils.getMapLong(reply, "recheck-in-mins",
-						PlatformMessenger.REPLY_EXCEPTION.equals(replyType)
-								? ERROR_RECHECKIN_MINS : DEFAULT_RECHECKIN_MINS);
-
-				resetTimerEvent(recheckInMins);
-
-				for (Iterator iter = list.iterator(); iter.hasNext();) {
-					Map map = (Map) iter.next();
-
-					String pkSender = MapUtils.getMapString(map, "sender", null);
-					long addedOn = SystemTime.getOffsetTime(MapUtils.getMapLong(map,
-							"added-secs-ago", 0)
-							* -1000);
-					VuzeBuddy buddy = VuzeBuddyManager.getBuddyByPK(pkSender);
-
-					BuddyPluginBuddy pluginBuddy = buddyPlugin.getBuddyFromPublicKey(pkSender);
-
-					long ack_id = MapUtils.getMapLong(map, "id", -1);
-					byte[] enc_payload = Base32.decode(MapUtils.getMapString(map,
-							"payload", ""));
-
-					cryptoResult decrypt;
-					try {
-						if (pluginBuddy == null) {
-							decrypt = buddyPlugin.decrypt(pkSender, enc_payload);
-						} else {
-							decrypt = pluginBuddy.decrypt(enc_payload);
-						}
-
-						byte[] payload = decrypt.getPayload();
-
-						Map decodedMap = BDecoder.decode(payload);
-
-						PlatformMessenger.debug("Relay: got message from " + pkSender);
-
-						if (TEST_ERRORACK) {
-							errorAck(ack_id);
-						} else {
-							ack(ack_id, decrypt.getChallenge());
-						}
-
-						for (Iterator iter2 = listeners.iterator(); iter2.hasNext();) {
-							VuzeRelayListener l = (VuzeRelayListener) iter2.next();
-							l.newRelayServerPayLoad(buddy, pkSender, decodedMap, addedOn);
-						}
-
-
-					} catch (BuddyPluginPasswordException e) {
-
-						// TODO we don't want to negative ack the message when we failed
-						// to decrypt because not logged in...
-
-					} catch (Exception e) {
-						PlatformMessenger.debug("Relay: send ack_fail: " + e.toString());
-						errorAck(ack_id);
-					}
-				}
-				// "date" also sent, but not needed (?)
-			}
-		};
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
-	/**
-	 * 
-	 *
-	 * @param recheckInMins 
-	 * @since 3.0.5.3
-	 */
-	protected static void resetTimerEvent(long recheckInMins) {
-		PlatformMessenger.debug("Relay: rechecking in " + recheckInMins + "m");
-
-		if (timerEvent != null) {
-			timerEvent.cancel();
-		}
-		timerEvent = SimpleTimer.addEvent("Relay Server Check",
-				SystemTime.getOffsetTime(recheckInMins * 1000l * 60),
-				relayCheckPerformer);
-	}
-
-	public static final void addRelayServerListener(VuzeRelayListener l) {
-		listeners.add(l);
-	}
-
-	public static final void removeRelayServerListener(VuzeRelayListener l) {
-		listeners.remove(l);
-	}
-
-	private static final void ack(long id, byte[] ack) {
-		String myPK;
-		try {
-			myPK = VuzeCryptoManager.getSingleton().getPublicKey(null);
-		} catch (VuzeCryptoException e) {
-			Debug.out(e);
-			return;
-		}
-
-		Map mapACK = new HashMap();
-		mapACK.put("id", new Long(id));
-		mapACK.put("ack", Base32.encode(ack));
-
-		Map mapParameters = new HashMap();
-		mapParameters.put("recipient_pk", myPK);
-		mapParameters.put("acks", new Object[] {
-			mapACK
-		});
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-
-			public void replyReceived(PlatformMessage message, String replyType,
-					Map reply) {
-				int numDeleted = MapUtils.getMapInt(reply, "deleted", 0);
-				PlatformMessenger.debug("Relay: deleted " + numDeleted);
-			}
-
-			public void messageSent(PlatformMessage message) {
-			}
-		};
-
-		PlatformMessage message = new PlatformMessage(MSG_ID, LISTENER_ID, OP_ACK,
-				mapParameters, 500);
-
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
-	private static final void errorAck(long id) {
-		String myPK;
-		try {
-			myPK = VuzeCryptoManager.getSingleton().getPublicKey("errorAck");
-		} catch (VuzeCryptoException e) {
-			Debug.out(e);
-			return;
-		}
-
-		// The ack is a String version of the id, encrypted, and base32 encoded
-		byte[] encryptBytes;
-		try {
-			byte[] content = String.valueOf(id).getBytes("UTF-8");
-			CryptoHandler ecc_handler = CryptoManagerFactory.getSingleton().getECCHandler();
-			encryptBytes = ecc_handler.sign(content, "Encrypting message for " + myPK);
-
-			//try {
-			//	System.err.println("Verify says: "
-			//			+ ecc_handler.verify(Base32.decode(myPK), content, encryptBytes));
-			//} catch (CryptoManagerException ee) {
-			//	ee.printStackTrace();
-			//}
-
-		} catch (Exception e) {
-			e.printStackTrace();
-			return;
-		}
-		String s = Base32.encode(encryptBytes);
-
-		Map mapACK = new HashMap();
-		mapACK.put("id", new Long(id));
-		mapACK.put("signature", s);
-
-		Map mapParameters = new HashMap();
-		mapParameters.put("recipient_pk", myPK);
-		mapParameters.put("error_acks", new Object[] {
-			mapACK
-		});
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-
-			public void replyReceived(PlatformMessage message, String replyType,
-					Map reply) {
-				int numDeleted = MapUtils.getMapInt(reply, "deleted", 0);
-				PlatformMessenger.debug("Relay: deleted " + numDeleted);
-			}
-
-			public void messageSent(PlatformMessage message) {
-			}
-		};
-
-		PlatformMessage message = new PlatformMessage(MSG_ID, LISTENER_ID,
-				OP_ERRORACK, mapParameters, 500);
-
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
-	public static void relayCheck() {
-		if (!VuzeCryptoManager.getSingleton().hasPublicKey()) {
-			return;
-		}
-
-		String myPK;
-		try {
-			myPK = VuzeCryptoManager.getSingleton().getPublicKey(null);
-		} catch (VuzeCryptoException e) {
-			Debug.out(e);
-			return;
-		}
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-
-			public void replyReceived(PlatformMessage message, String replyType,
-					Map reply) {
-				int count = MapUtils.getMapInt(reply, "count", 0);
-				long recheckInMins = MapUtils.getMapLong(reply, "recheck-in-mins",
-						PlatformMessenger.REPLY_EXCEPTION.equals(replyType)
-								? ERROR_RECHECKIN_MINS : DEFAULT_RECHECKIN_MINS);
-				resetTimerEvent(recheckInMins);
-
-				if (count > 0 || lastPendingCount != count) {
-					lastPendingCount = count;
-					for (Iterator iter2 = listeners.iterator(); iter2.hasNext();) {
-						VuzeRelayListener l = (VuzeRelayListener) iter2.next();
-						l.hasPendingRelayMessage(count);
-					}
-				}
-			}
-
-			public void messageSent(PlatformMessage message) {
-			}
-		};
-
-		PlatformMessage message = new PlatformMessage(MSG_ID, LISTENER_ID,
-				OP_COUNT, new Object[] {
-					"pk",
-					myPK
-				}, 0);
-
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
-	public interface putListener
-	{
-		public void putOK(BuddyPluginBuddyMessage message);
-
-		public void putFailed(BuddyPluginBuddyMessage message, Throwable cause);
-	}
-}
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformSubscriptionsMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformSubscriptionsMessenger.java
index c914032..b6818b0 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformSubscriptionsMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformSubscriptionsMessenger.java
@@ -35,6 +35,8 @@ import com.aelitis.azureus.core.security.CryptoECCUtils;
 public class 
 PlatformSubscriptionsMessenger 
 {
+	private static final boolean	MESSAGING_ENABLED = true;
+	
 	private static final PlatformMessengerConfig	dispatcher = 
 		new PlatformMessengerConfig( "subscription", false );
 
@@ -56,6 +58,10 @@ PlatformSubscriptionsMessenger
 	
 		throws PlatformMessengerException
 	{
+		String operation = create?OP_CREATE_SUBS:OP_UPDATE_SUBS;
+		
+		checkEnabled( operation );
+		
 		Map parameters = new HashMap();
 		
 		String	sid_str = Base32.encode( sid );
@@ -88,7 +94,7 @@ PlatformSubscriptionsMessenger
 			
 			parameters.put( "signature", Base32.encode( sig_bytes ));
 
-			dispatcher.syncInvoke(	create?OP_CREATE_SUBS:OP_UPDATE_SUBS, parameters ); 
+			dispatcher.syncInvoke( operation, parameters ); 
 			
 		}catch( Throwable e ){
 			
@@ -102,6 +108,8 @@ PlatformSubscriptionsMessenger
 	
 		throws PlatformMessengerException
 	{
+		checkEnabled( OP_GET_SUBS_BY_SID );
+		
 		Map parameters = new HashMap();
 		
 		List	sid_list = new JSONArray();
@@ -133,6 +141,8 @@ PlatformSubscriptionsMessenger
 	
 		throws PlatformMessengerException
 	{
+		checkEnabled( OP_GET_POP_BY_SID );
+		
 		Map parameters = new HashMap();
 		
 		List	sid_list = new JSONArray();
@@ -164,6 +174,8 @@ PlatformSubscriptionsMessenger
 	
 		throws PlatformMessengerException
 	{
+		checkEnabled( OP_SET_SELECTED );
+		
 		Map parameters = new HashMap();
 		
 		List	sid_list 	= new JSONArray();		
@@ -174,7 +186,7 @@ PlatformSubscriptionsMessenger
 		
 		parameters.put( "subscription_ids", sid_list);
 		
-		Map reply = dispatcher.syncInvoke(	OP_SET_SELECTED, parameters ); 
+		Map reply = dispatcher.syncInvoke( OP_SET_SELECTED, parameters ); 
 		
 		List	versions = (List)reply.get( "version_numbers" );
 		
@@ -207,6 +219,17 @@ PlatformSubscriptionsMessenger
 		return( new List[]{ versions,popularities } );
 	}   
 	
+	protected static void
+	checkEnabled(
+		String		method )
+	
+		throws PlatformMessengerException
+	{
+		if ( !MESSAGING_ENABLED ){
+			
+			throw( new PlatformMessengerException( "messaging disabled" ));
+		}
+	}
 	
 	public static class
 	subscriptionInfo
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformTorrentMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformTorrentMessenger.java
index 27a19f6..1893f9f 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformTorrentMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformTorrentMessenger.java
@@ -20,14 +20,14 @@
 
 package com.aelitis.azureus.core.messenger.config;
 
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.torrent.TOTorrentException;
 
 import com.aelitis.azureus.core.messenger.PlatformMessage;
 import com.aelitis.azureus.core.messenger.PlatformMessenger;
-import com.aelitis.azureus.core.messenger.PlatformMessengerListener;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 
 /**
@@ -39,81 +39,8 @@ public class PlatformTorrentMessenger
 {
 	public static String LISTENER_ID = "torrent";
 
-	public static String OP_GETMETADATA = "get-metadata";
-
 	public static String OP_STREAMCOMPLETE = "stream-complete";
 
-	public static interface GetMetaDataReplyListener
-	{
-		public void messageSent();
-
-		public void replyReceived(String replyType, Map mapHashes);
-	}
-
-	/**
-	 * @param torrent
-	 * @param maxDelayMS
-	 * @param replyListener
-	 *
-	 * @since 3.0.0.7
-	 */
-	public static void getMetaData(long contentNetworkID, TOTorrent[] torrents,
-			long maxDelayMS, final GetMetaDataReplyListener replyListener) {
-		Map mapParameters = new HashMap();
-		List listContent = new ArrayList();
-		List listHashes = new ArrayList();
-		mapParameters.put("content-list", listContent);
-		if (PlatformConfigMessenger.getRPCVersion() == 0) {
-			// legacy support
-			mapParameters.put("hashes", listHashes);
-		}
-
-		for (int i = 0; i < torrents.length; i++) {
-			TOTorrent torrent = torrents[i];
-			if (!PlatformTorrentUtils.isContent(torrent, true)) {
-				continue;
-			}
-
-			String hash = null;
-			try {
-				hash = torrent.getHashWrapper().toBase32String();
-			} catch (TOTorrentException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-
-			if (hash != null) {
-				listHashes.add(hash);
-
-				Map jsonSubObject = new HashMap();
-				listContent.add(jsonSubObject);
-				jsonSubObject.put("hash", hash);
-				jsonSubObject.put("last-revision", new Long(
-						PlatformTorrentUtils.getContentLastUpdated(torrent)));
-			}
-		}
-
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID,
-				OP_GETMETADATA, mapParameters, maxDelayMS);
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-			public void messageSent(PlatformMessage message) {
-				replyListener.messageSent();
-			}
-
-			public void replyReceived(PlatformMessage message, String replyType,
-					Map reply) {
-				if (reply != null) {
-					replyListener.replyReceived(replyType, reply);
-				} else {
-					replyListener.replyReceived(replyType, new HashMap());
-				}
-			}
-		};
-
-		PlatformMessenger.queueMessage(message, listener);
-	}
-
 	public static void streamComplete(TOTorrent torrent, long waitTime,
 			int maxSeekAheadSecs, int numRebuffers, int numHardRebuffers) {
 		String hash = null;
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformVuzeActivitiesMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformVuzeActivitiesMessenger.java
index 192a61f..d05a44b 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformVuzeActivitiesMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformVuzeActivitiesMessenger.java
@@ -27,7 +27,6 @@ import com.aelitis.azureus.activities.VuzeActivitiesManager;
 import com.aelitis.azureus.core.messenger.PlatformMessage;
 import com.aelitis.azureus.core.messenger.PlatformMessenger;
 import com.aelitis.azureus.core.messenger.PlatformMessengerListener;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.util.MapUtils;
 
 /**
diff --git a/com/aelitis/azureus/core/messenger/config/RatingUpdateListener2.java b/com/aelitis/azureus/core/messenger/config/RatingUpdateListener2.java
deleted file mode 100644
index 9b220f3..0000000
--- a/com/aelitis/azureus/core/messenger/config/RatingUpdateListener2.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Created on Mar 27, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
- 
-package com.aelitis.azureus.core.messenger.config;
-
-import com.aelitis.azureus.core.torrent.RatingInfoList;
-
-public interface RatingUpdateListener2
-{
-	public void ratingUpdated(RatingInfoList rating);
-}
\ No newline at end of file
diff --git a/com/aelitis/azureus/core/messenger/config/VuzeBuddySyncListener.java b/com/aelitis/azureus/core/messenger/config/VuzeBuddySyncListener.java
deleted file mode 100644
index 752ebac..0000000
--- a/com/aelitis/azureus/core/messenger/config/VuzeBuddySyncListener.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Created on Apr 22, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
- 
-package com.aelitis.azureus.core.messenger.config;
-
-/**
- * @author TuxPaper
- * @created Apr 22, 2008
- *
- */
-public interface VuzeBuddySyncListener
-{
-	public void syncComplete();
-}
diff --git a/com/aelitis/azureus/core/messenger/config/VuzeRelayListener.java b/com/aelitis/azureus/core/messenger/config/VuzeRelayListener.java
deleted file mode 100644
index 13c6d35..0000000
--- a/com/aelitis/azureus/core/messenger/config/VuzeRelayListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Created on Apr 17, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.core.messenger.config;
-
-import java.util.Map;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-
-/**
- * @author TuxPaper
- * @created Apr 17, 2008
- *
- */
-public interface VuzeRelayListener
-{
-	public void newRelayServerPayLoad(VuzeBuddy sender, String pkSender,
-			Map decodedMap, long addedOn);
-
-	public void hasPendingRelayMessage(int count);
-}
diff --git a/com/aelitis/azureus/core/metasearch/Engine.java b/com/aelitis/azureus/core/metasearch/Engine.java
index 511aeeb..d075cc6 100644
--- a/com/aelitis/azureus/core/metasearch/Engine.java
+++ b/com/aelitis/azureus/core/metasearch/Engine.java
@@ -97,6 +97,7 @@ Engine
 	public static final String	SC_SOURCE			= "azsrc";
 	public static final String	SC_AZID				= "azid";
 	public static final String	SC_FORCE_FULL		= "force_full";	// ignore if-modified stuff and force a full search
+	public static final String	SC_BATCH_PERIOD		= "batch_millis";
 	
 	public static final String	CT_VIDEO	= "video";
 	public static final String	CT_AUDIO	= "audio";
diff --git a/com/aelitis/azureus/core/metasearch/Result.java b/com/aelitis/azureus/core/metasearch/Result.java
index 8edee94..8d23db0 100644
--- a/com/aelitis/azureus/core/metasearch/Result.java
+++ b/com/aelitis/azureus/core/metasearch/Result.java
@@ -20,7 +20,10 @@
 
 package com.aelitis.azureus.core.metasearch;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Random;
 import java.util.StringTokenizer;
@@ -151,12 +154,38 @@ public abstract class Result {
 		String queryString = getSearchQuery();
 		String name = getName();
 		if(queryString != null && name != null) {
-			name = name.toLowerCase();
-			//TODO :  METASEARCH Change this as soon as Gouss sends a non escaped string
-			StringTokenizer st = new StringTokenizer(queryString, " ");
-			while(st.hasMoreElements()) {
-				String match = st.nextToken().toLowerCase();
-				if(name.indexOf(match) == -1) {
+			name = name.toLowerCase( Locale.ENGLISH );
+			
+			String	token = "";
+			
+			List<String>	tokens = new ArrayList<String>();
+			
+			char[] chars = queryString.toCharArray();
+			
+			for ( char c: chars ){
+			
+				if ( Character.isLetterOrDigit( c )){
+					
+					token += String.valueOf(c).toLowerCase( Locale.ENGLISH );
+					
+				}else{
+					
+					if ( token.length() > 0 ){
+						
+						tokens.add( token );
+						
+						token = "";
+					}
+				}
+			}
+
+			if ( token.length() > 0 ){
+				
+				tokens.add( token );
+			}
+			
+			for ( String s: tokens ){
+				if( !name.contains( s )){
 					rank /= 2;
 				}
 			}
diff --git a/com/aelitis/azureus/core/metasearch/impl/DateParserRegex.java b/com/aelitis/azureus/core/metasearch/impl/DateParserRegex.java
index b2e8560..5a7d5ee 100644
--- a/com/aelitis/azureus/core/metasearch/impl/DateParserRegex.java
+++ b/com/aelitis/azureus/core/metasearch/impl/DateParserRegex.java
@@ -117,6 +117,13 @@ public class DateParserRegex extends DateParser {
 		//Remove the time information in order to not confuse the date parsing
 		s = matcher.replaceFirst("").trim();
 		
+			// handle date with format "2009-01-12 at 03:36:38" by removing trailing " at";
+		
+		if ( s.endsWith( " at" )){
+			
+			s = s.substring(0,s.length()-3).trim();
+		}
+		
 		//Find if the date contains letters
 		matcher = hasLettersPattern.matcher(s);
 		if(matcher.find()) {
@@ -448,7 +455,7 @@ public class DateParserRegex extends DateParser {
 		dateParser.parseDate("2008.04.28");	//
 		dateParser.parseDate("16/04/08");	//
 		dateParser.parseDate("20-Dec-07");	//
-		
+		dateParser.parseDate("2009-01-12 at 03:36:38" );
 	}
 	
 
diff --git a/com/aelitis/azureus/core/metasearch/impl/EngineImpl.java b/com/aelitis/azureus/core/metasearch/impl/EngineImpl.java
index 91062bc..9659a61 100644
--- a/com/aelitis/azureus/core/metasearch/impl/EngineImpl.java
+++ b/com/aelitis/azureus/core/metasearch/impl/EngineImpl.java
@@ -30,6 +30,7 @@ import java.util.*;
 
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AEDiagnostics;
 import org.gudy.azureus2.core3.util.BEncoder;
@@ -65,6 +66,24 @@ EngineImpl
 {
 	private static final int DEFAULT_UPDATE_CHECK_SECS = 24*60*60;
 	
+	private static boolean logging_enabled;
+	
+	static{
+		COConfigurationManager.addAndFireParameterListeners(
+			new String[]{
+				"Logger.Enabled",
+			},
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					String parameterName) 
+				{			
+					logging_enabled = COConfigurationManager.getBooleanParameter( "Logger.Enabled" );
+				}
+			});
+	}
+	
 	protected static EngineImpl
 	importFromBEncodedMap(
 		MetaSearchImpl		meta_search,
@@ -645,12 +664,12 @@ EngineImpl
 		
 	public Result[]
 	search(
-		SearchParameter[] 	params,
-		Map					context,
-		int					desired_max_matches,
-		int					absolute_max_matches,
-		String				headers,
-		ResultListener		listener )
+		SearchParameter[] 		params,
+		Map						context,
+		int						desired_max_matches,
+		int						absolute_max_matches,
+		String					headers,
+		final ResultListener	listener )
 	
 		throws SearchException
 	{
@@ -660,13 +679,99 @@ EngineImpl
 		}
 		
 		try{
-			Result[] results = searchAndMap( params, context, desired_max_matches, absolute_max_matches, headers, listener) ;
+			final Set<Result>		results_informed 	= new HashSet<Result>();
+			final boolean[]			complete_informed	= { false };
+			
+			ResultListener	interceptor = 
+				new ResultListener()
+				{
+					public void 
+					contentReceived(
+						Engine 		engine, 
+						String 		content )
+					{
+						listener.contentReceived(engine, content);
+					}
+				
+					public void 
+					matchFound( 
+						Engine engine, 
+						String[] fields )
+					{
+						listener.matchFound(engine, fields);
+					}
+				
+					public void 
+					resultsReceived(
+						Engine engine,
+						Result[] 	results )
+					{
+						listener.resultsReceived(engine, results);
+						
+						synchronized( results_informed ){
+							
+							results_informed.addAll( Arrays.asList( results ));
+						}
+					}
+				
+					public void 
+					resultsComplete(
+						Engine 		engine)
+					{
+						listener.resultsComplete(engine);
+						
+						synchronized( results_informed ){
+							
+							complete_informed[0] = true;
+						}
+					}
+				
+					public void 
+					engineFailed(
+						Engine 		engine, 
+						Throwable 	cause )
+					{
+						listener.engineFailed(engine, cause);
+					}
+					
+					public void 
+					engineRequiresLogin(
+						Engine 		engine, 
+						Throwable 	cause )
+					{
+						listener.engineRequiresLogin(engine, cause);
+					}
+				};
+				
+			Result[] results = searchAndMap( params, context, desired_max_matches, absolute_max_matches, headers, listener==null?null:interceptor );
 			
 			if ( listener != null ){
 				
-				listener.resultsReceived( this, results );
+				boolean			inform_complete;
+				List<Result>	inform_result = new ArrayList<Result>();
+				
+				synchronized( results_informed ){
+					
+					for ( Result r: results ){
+						
+						if ( !results_informed.contains( r )){
+							
+							inform_result.add( r );
+						}
+					}
+					
+					inform_complete = !complete_informed[0];
+				}
 				
-				listener.resultsComplete( this );
+				if ( inform_result.size() > 0 ){
+				
+					listener.resultsReceived( this, inform_result.toArray( new Result[ inform_result.size()] ));
+				}
+				
+				if ( inform_complete ){
+				
+					listener.resultsComplete( this );
+				}
 			}
 			
 			return( results );
@@ -1294,13 +1399,25 @@ EngineImpl
 	protected File
 	getDebugFile()
 	{
-		return( new File( AEDiagnostics.getLogDir(), "MetaSearch_Engine_" + getId() + ".txt" ));
+		if ( logging_enabled ){
+		
+			return( new File( AEDiagnostics.getLogDir(), "MetaSearch_Engine_" + getId() + ".txt" ));
+			
+		}else{
+			
+			return( null );
+		}
 	}
 	
 	protected synchronized void
 	debugStart()
 	{
-		getDebugFile().delete();
+		File f = getDebugFile();
+		
+		if ( f != null ){
+			
+			f.delete();
+		}
 	}
 	
 	protected synchronized void
@@ -1309,20 +1426,23 @@ EngineImpl
 	{
 		File f = getDebugFile();
 		
-		PrintWriter	 pw = null;
-		
-		try{
-			pw = new PrintWriter(new FileWriter( f, true ));
-			
-			pw.println( str );
-			
-		}catch( Throwable e ){
+		if ( f != null ){
 			
-		}finally{
+			PrintWriter	 pw = null;
 			
-			if ( pw != null ){
+			try{
+				pw = new PrintWriter(new FileWriter( f, true ));
+				
+				pw.println( str );
+				
+			}catch( Throwable e ){
+				
+			}finally{
 				
-				pw.close();
+				if ( pw != null ){
+					
+					pw.close();
+				}
 			}
 		}
 	}
diff --git a/com/aelitis/azureus/core/metasearch/impl/ExternalLoginWindow.java b/com/aelitis/azureus/core/metasearch/impl/ExternalLoginWindow.java
index d59477f..df4a336 100644
--- a/com/aelitis/azureus/core/metasearch/impl/ExternalLoginWindow.java
+++ b/com/aelitis/azureus/core/metasearch/impl/ExternalLoginWindow.java
@@ -20,15 +20,13 @@ import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Shell;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.ui.swt.ImageRepository;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.progress.ProgressWindow;
 
 import com.aelitis.azureus.core.metasearch.impl.web.WebEngine;
 import com.aelitis.azureus.core.util.http.HTTPAuthHelper;
 import com.aelitis.azureus.core.util.http.HTTPAuthHelperListener;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 import com.aelitis.azureus.ui.swt.browser.CookiesListener;
 import com.aelitis.azureus.ui.swt.browser.listener.ExternalLoginCookieListener;
 
@@ -61,18 +59,9 @@ public class ExternalLoginWindow {
 		listener			= _listener;
 		originalLoginUrl 	= _loginUrl;
 
-		UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
-		if(functionsSWT != null) {
-			Shell mainShell = functionsSWT.getMainShell();
-			shell = new Shell(mainShell,SWT.TITLE | SWT.CLOSE);
-			shell.setSize(800,600);
-			Utils.centerWindowRelativeTo(shell, mainShell);
-			
-		} else {
-			shell = new Shell(SWT.TITLE | SWT.CLOSE);
-			shell.setSize(800,600);
-			Utils.centreWindow(shell);
-		}
+		shell = ShellFactory.createMainShell(SWT.TITLE | SWT.CLOSE);
+		shell.setSize(800,600);
+		Utils.centreWindow(shell);
 		
 		display = shell.getDisplay();
 		shell.setText(MessageText.getString("externalLogin.title"));
@@ -101,7 +90,11 @@ public class ExternalLoginWindow {
 			explain.setText(MessageText.getString("externalLogin.explanation", new String[]{ name }));
 		}
 		
-		browser = new Browser(shell,Utils.getInitialBrowserStyle(SWT.BORDER));
+		browser = Utils.createSafeBrowser(shell, SWT.BORDER);
+		if (browser == null) {
+			shell.dispose();
+			return;
+		}
 		final ExternalLoginCookieListener cookieListener = new ExternalLoginCookieListener(new CookiesListener() {
 			public void cookiesFound(String cookies){
 				foundCookies( cookies, true );
@@ -236,6 +229,9 @@ public class ExternalLoginWindow {
 					completed(
 						ProgressEvent arg0 ) 
 					{
+						if (browser.isDisposed() || browser.getShell().isDisposed()) {
+							return;
+						}
 						browser.removeProgressListener( this );
 						
 						prog_wind.destroy();
@@ -374,10 +370,6 @@ public class ExternalLoginWindow {
 	public void close() {
 		Utils.execSWTThread(new Runnable() {
 			public void run() {
-				if(browser!=null && !browser.isDisposed()){
-					//OSX browser disposal bug -- workaround for limiting memory leak
-					browser.setUrl("about:blank");
-				}
 				shell.close();
 			}
 		});
diff --git a/com/aelitis/azureus/core/metasearch/impl/MetaSearchImpl.java b/com/aelitis/azureus/core/metasearch/impl/MetaSearchImpl.java
index 19bede9..fc7136a 100644
--- a/com/aelitis/azureus/core/metasearch/impl/MetaSearchImpl.java
+++ b/com/aelitis/azureus/core/metasearch/impl/MetaSearchImpl.java
@@ -718,6 +718,10 @@ MetaSearchImpl
 			param_str += (i==0?"":",") + param.getMatchPattern() + "->" + param.getValue();
 		}
 		
+		String batch_millis_str = context.get( Engine.SC_BATCH_PERIOD );
+		
+		final long batch_millis = batch_millis_str==null?0:Long.parseLong( batch_millis_str );
+		
 		ResultListener	listener = 
 			new ResultListener()
 			{
@@ -725,6 +729,8 @@ MetaSearchImpl
 			
 				private AsyncDispatcher dispatcher = new AsyncDispatcher( 5000 );
 
+				final private Map<Engine,List<Result[]>>	pending_results = new HashMap<Engine,List<Result[]>>();
+				
 				public void 
 				contentReceived(
 					final Engine engine, 
@@ -768,9 +774,52 @@ MetaSearchImpl
 							public void
 							runSupport()
 							{
-								Result[] results_to_return = truncateResults( engine, results, max_results_per_engine );
+								Result[] results_to_return = null;
+								
+								if ( batch_millis > 0 ){
+									
+									List<Result[]> list = pending_results.get( engine );
+																		
+									if ( list == null ){
+																			
+										results_to_return = results;
+										
+										pending_results.put( engine, new ArrayList<Result[]>());
+										
+										new DelayedEvent(
+											"SearchBatcher",
+											batch_millis,
+											new AERunnable()
+											{
+												public void 
+												runSupport() 
+												{
+													dispatcher.dispatch(
+														new AERunnable()
+														{
+															public void 
+															runSupport() 
+															{
+																batchResultsComplete( engine );
+															}
+														});
+												}
+											});
+									}else{
+																															
+										list.add( results );
+									}
+								}else{
 								
-								original_listener.resultsReceived( engine, results_to_return );
+									results_to_return = results;
+								}
+								
+								if ( results_to_return != null ){
+									
+									results_to_return = truncateResults( engine, results_to_return, max_results_per_engine );
+									
+									original_listener.resultsReceived( engine, results_to_return );
+								}
 							}
 						});
 				}
@@ -785,11 +834,39 @@ MetaSearchImpl
 								public void
 								runSupport()
 								{
+									if ( batch_millis > 0 ){
+
+										batchResultsComplete( engine );
+									}
+									
 									original_listener.resultsComplete( engine );
 								}
 							});
 				}
 			
+				protected void
+				batchResultsComplete(
+					Engine engine )
+				{
+					List<Result[]> list = pending_results.remove( engine );
+					
+					if ( list != null ){
+						
+						List<Result> x = new ArrayList<Result>();
+						
+						for ( Result[] y: list ){
+							
+							x.addAll( Arrays.asList( y ));
+						}
+						
+						Result[] results = x.toArray( new Result[ x.size()]);
+					
+						results = truncateResults( engine, results, max_results_per_engine );
+					
+						original_listener.resultsReceived( engine, results );
+					}
+				}
+				
 				public void 
 				engineFailed(
 					final Engine 	engine,
diff --git a/com/aelitis/azureus/core/metasearch/impl/MetaSearchManagerImpl.java b/com/aelitis/azureus/core/metasearch/impl/MetaSearchManagerImpl.java
index 235749d..0fa3fae 100644
--- a/com/aelitis/azureus/core/metasearch/impl/MetaSearchManagerImpl.java
+++ b/com/aelitis/azureus/core/metasearch/impl/MetaSearchManagerImpl.java
@@ -754,7 +754,7 @@ MetaSearchManagerImpl
 					Engine	engine = engines[i];
 					
 					if ( 	engine.getSource() == Engine.ENGINE_SOURCE_VUZE &&
-							engine.getSelectionState() != Engine.SEL_STATE_DESELECTED &&
+							engine.getSelectionState() == Engine.SEL_STATE_AUTO_SELECTED &&
 							!vuze_selected_ids.containsKey( new Long( engine.getId()))){
 						
 						log( "Deselecting " + engine.getString() + " as no longer visible on Vuze");
@@ -921,6 +921,8 @@ MetaSearchManagerImpl
 			}
 		}catch( Throwable e ){
 			
+			e.printStackTrace();
+			
 			if ( e instanceof MetaSearchException ){
 				
 				throw((MetaSearchException)e);
diff --git a/com/aelitis/azureus/core/metasearch/impl/plugin/PluginEngine.java b/com/aelitis/azureus/core/metasearch/impl/plugin/PluginEngine.java
index a61b3e3..b782b1c 100644
--- a/com/aelitis/azureus/core/metasearch/impl/plugin/PluginEngine.java
+++ b/com/aelitis/azureus/core/metasearch/impl/plugin/PluginEngine.java
@@ -229,12 +229,12 @@ PluginEngine
 	
 	protected Result[] 
 	searchSupport(
-		SearchParameter[] 	params, 
-		Map					searchContext,
-		final int 			desired_max_matches,
-		final int			absolute_max_matches,
-		String 				headers, 
-		ResultListener 		listener )
+		SearchParameter[] 		params, 
+		Map						searchContext,
+		final int 				desired_max_matches,
+		final int				absolute_max_matches,
+		String 					headers, 
+		final ResultListener 	listener )
 	
 		throws SearchException 
 	{
@@ -273,7 +273,7 @@ PluginEngine
 		final String f_term = term;
 		
 		try{
-			final List	results = new ArrayList();
+			final List<PluginResult>	results = new ArrayList<PluginResult>();
 			
 			final AESemaphore	sem = new AESemaphore( "waiter" );
 
@@ -288,6 +288,8 @@ PluginEngine
 						SearchInstance 		search,
 						SearchResult 		result )
 					{
+						PluginResult p_result = new PluginResult( PluginEngine.this, result, f_term );
+						
 						synchronized( this ){
 							
 							if ( complete ){
@@ -295,8 +297,16 @@ PluginEngine
 								return;
 							}
 							
-							results.add( new PluginResult( PluginEngine.this, result, f_term ));
+							results.add( p_result );
+						}
+						
+						if ( listener != null ){
 							
+							listener.resultsReceived( PluginEngine.this, new Result[]{ p_result });
+						}
+						
+						synchronized( this ){
+
 							if ( absolute_max_matches >= 0 && results.size() >= absolute_max_matches ){
 								
 								complete = true;
@@ -333,6 +343,11 @@ PluginEngine
 			
 			sem.reserve();
 			
+			if ( listener != null ){
+				
+				listener.resultsComplete( this );
+			}
+			
 			return((Result[])results.toArray(new Result[results.size()]));
 			
 		}catch( Throwable e ){
diff --git a/com/aelitis/azureus/core/metasearch/impl/plugin/PluginResult.java b/com/aelitis/azureus/core/metasearch/impl/plugin/PluginResult.java
index 136ae2a..72c9def 100644
--- a/com/aelitis/azureus/core/metasearch/impl/plugin/PluginResult.java
+++ b/com/aelitis/azureus/core/metasearch/impl/plugin/PluginResult.java
@@ -199,6 +199,13 @@ PluginResult
 		}
 		
 		long	l_rank = getLongProperty( SearchResult.PR_RANK );
+
+			// if we have seeds/peers just use the usual mechanism
+		
+		if ( getLongProperty( SearchResult.PR_SEED_COUNT ) >= 0 && getLongProperty( SearchResult.PR_LEECHER_COUNT ) >= 0 ){
+			
+			l_rank = Long.MIN_VALUE;
+		}
 		
 		if ( l_rank == Long.MIN_VALUE ){
 			
diff --git a/com/aelitis/azureus/core/metasearch/impl/web/WebResult.java b/com/aelitis/azureus/core/metasearch/impl/web/WebResult.java
index 1426155..9c2b29a 100644
--- a/com/aelitis/azureus/core/metasearch/impl/web/WebResult.java
+++ b/com/aelitis/azureus/core/metasearch/impl/web/WebResult.java
@@ -61,6 +61,7 @@ public class WebResult extends Result {
 	int	comments	= -1;
 	int votes = -1;
 	int votesDown = -1;
+	float rank = -1;
 	
 	boolean privateTorrent;
 	
@@ -181,6 +182,41 @@ public class WebResult extends Result {
 		}
 	}
 	
+	public void setRankFromHTML( String rank_str ){
+		if ( rank_str != null ){
+			try{
+					// either a float 0->1 or integer 0->100
+				
+				float f = Float.parseFloat( rank_str.trim() );
+				
+				if ( rank_str.indexOf( "." ) == -1 ){
+					
+					if ( f >= 0 &&  f <= 100 ){
+						
+						rank = f/100;
+					}
+				}else{
+					
+					if ( f >= 0 &&  f <= 1 ){
+						
+						rank = f;
+					}
+				}
+			}catch( Throwable e ){
+			}
+		}
+	}
+	
+	public float
+	getRank()
+	{
+		if ( rank != -1 ){
+			return( rank );
+		}
+		
+		return( super.getRank());
+	}
+	
 	public void setPublishedDate(Date date) {
 		this.publishedDate = date;
 	}
diff --git a/com/aelitis/azureus/core/metasearch/impl/web/rss/RSSEngine.java b/com/aelitis/azureus/core/metasearch/impl/web/rss/RSSEngine.java
index c38cdff..07a0e1f 100644
--- a/com/aelitis/azureus/core/metasearch/impl/web/rss/RSSEngine.java
+++ b/com/aelitis/azureus/core/metasearch/impl/web/rss/RSSEngine.java
@@ -8,6 +8,8 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.SystemTime;
@@ -34,6 +36,8 @@ public class
 RSSEngine 
 	extends WebEngine 
 {
+	private Pattern seed_leecher_pat = Pattern.compile("([0-9]+)\\s+(seed|leecher)s", Pattern.CASE_INSENSITIVE);
+
 	public static EngineImpl
 	importFromBEncodedMap(
 		MetaSearchImpl		meta_search,
@@ -245,6 +249,8 @@ RSSEngine
 						result.setUID( uid );
 					}
 					
+					boolean got_seeds_peers = false;
+					
 					SimpleXMLParserDocumentNode node = item.getNode();
 					
 					if ( node != null ){
@@ -381,16 +387,26 @@ RSSEngine
 								
 							}else if ( lc_full_child_name.equals( "vuze:seeds" )){
 								
+								got_seeds_peers = true;
+								
 								result.setNbSeedsFromHTML( value );
 								
 							}else if ( lc_full_child_name.equals( "vuze:superseeds" )){
 								
+								got_seeds_peers = true;
+								
 								result.setNbSuperSeedsFromHTML( value );
 								
 							}else if ( lc_full_child_name.equals( "vuze:peers" )){
 								
+								got_seeds_peers = true;
+								
 								result.setNbPeersFromHTML( value );
 								
+							}else if ( lc_full_child_name.equals( "vuze:rank" )){
+								
+								result.setRankFromHTML( value );
+								
 							}else if ( lc_full_child_name.equals( "vuze:contenttype" )){
 								
 								String	type = value.toLowerCase();
@@ -429,6 +445,41 @@ RSSEngine
 						}
 					}
 					
+					if ( !got_seeds_peers ){
+						
+						try{
+							SimpleXMLParserDocumentNode desc_node = node.getChild( "description" );
+							
+							if ( desc_node != null ){
+								
+								String desc = desc_node.getValue().trim();
+								
+									// see if we can pull from description
+								
+								Matcher m = seed_leecher_pat.matcher( desc );
+							
+								while( m.find()){
+									
+									String	num = m.group(1);
+									
+									String	type = m.group(2);
+									
+									if ( type.toLowerCase().charAt(0) == 's' ){
+										
+										result.setNbSeedsFromHTML( num );
+										
+									}else{
+										
+										result.setNbPeersFromHTML( num );
+									}
+								}
+							}
+							
+						}catch( Throwable e ){
+							
+						}
+					}
+					
 					results.add(result);
 					
 					if ( absolute_max_matches >= 0 && results.size() == absolute_max_matches ){
diff --git a/com/aelitis/azureus/core/metasearch/utils/MomentsAgoDateFormatter.java b/com/aelitis/azureus/core/metasearch/utils/MomentsAgoDateFormatter.java
index 89283f0..192aad6 100644
--- a/com/aelitis/azureus/core/metasearch/utils/MomentsAgoDateFormatter.java
+++ b/com/aelitis/azureus/core/metasearch/utils/MomentsAgoDateFormatter.java
@@ -66,8 +66,6 @@ public class MomentsAgoDateFormatter {
        CONVERSION_MAP.put(ID_WEEK_OF_YEAR, MS_IN_WEEK);
        CONVERSION_MAP.put(ID_DAY, MS_IN_DAY);
        CONVERSION_MAP.put(ID_HOUR_OF_DAY, MS_IN_HOUR);
-       CONVERSION_MAP.put(ID_MINUTE, MS_IN_MINUTE);
-       CONVERSION_MAP.put(ID_SECOND, MS_IN_SECOND);
    }
 
    private static final Map UNIT_MAP =
@@ -75,13 +73,11 @@ public class MomentsAgoDateFormatter {
 
    // Build the map at system start
    static {
-       UNIT_MAP.put(ID_YEAR, " year");
-       UNIT_MAP.put(ID_MONTH, " month");
-       UNIT_MAP.put(ID_WEEK_OF_YEAR, " week");
+       UNIT_MAP.put(ID_YEAR, " yr");
+       UNIT_MAP.put(ID_MONTH, " mo");
+       UNIT_MAP.put(ID_WEEK_OF_YEAR, " wk");
        UNIT_MAP.put(ID_DAY, " day");
-       UNIT_MAP.put(ID_HOUR_OF_DAY, " hour");
-       UNIT_MAP.put(ID_MINUTE, " minute");
-       UNIT_MAP.put(ID_SECOND, " second");
+       UNIT_MAP.put(ID_HOUR_OF_DAY, " hr");
    }
 
    /**
@@ -123,11 +119,7 @@ public class MomentsAgoDateFormatter {
                    if (result == null) {
                        result = handleUnit(then, now, ID_HOUR_OF_DAY);
                        if (result == null) {
-                           result = handleUnit(then, now, ID_MINUTE);
-                           if (result == null) {
-                               result = handleUnit(then, now, ID_SECOND);
-                               if (result == null) result = new String();
-                           }
+                           return "< 1 h";
                        }
                    }
                }
@@ -154,8 +146,8 @@ public class MomentsAgoDateFormatter {
        if (diff > comparison) {
            long timeAgo = diff / comparison;
            result = String.valueOf(timeAgo).concat((String)UNIT_MAP.get(field));
-           if (timeAgo > 1) result = result.concat(PLURAL);
-           result = result.concat(AGO);
+           //if (timeAgo > 1) result = result.concat(PLURAL);
+           //result = result.concat(AGO);
        }
        return result;
    }
diff --git a/com/aelitis/azureus/core/monitoring/thread/AEThreadMonitor.java b/com/aelitis/azureus/core/monitoring/thread/AEThreadMonitor.java
index 2b6806b..c1fc3cf 100644
--- a/com/aelitis/azureus/core/monitoring/thread/AEThreadMonitor.java
+++ b/com/aelitis/azureus/core/monitoring/thread/AEThreadMonitor.java
@@ -27,10 +27,7 @@ import java.io.StringWriter;
 import java.lang.management.ManagementFactory;
 import java.lang.management.ThreadInfo;
 import java.lang.management.ThreadMXBean;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 import org.gudy.azureus2.core3.util.*;
 
@@ -300,14 +297,17 @@ AEThreadMonitor
 		writer.println("Threads " + allThreadIds.length);
 		writer.indent();
 
-		ThreadInfo[] threadInfos = new ThreadInfo[allThreadIds.length];
+		List<ThreadInfo> threadInfos = new ArrayList<ThreadInfo>(allThreadIds.length);
 		for (int i = 0; i < allThreadIds.length; i++) {
-			threadInfos[i] = threadBean.getThreadInfo(allThreadIds[i], 32);
+			ThreadInfo info = threadBean.getThreadInfo(allThreadIds[i], 32);
+			if(info != null)
+				threadInfos.add(info);
 		}
 
 		if (!disable_getThreadCpuTime) {
-			Arrays.sort(threadInfos, new Comparator<ThreadInfo>() {
+			Collections.sort(threadInfos, new Comparator<ThreadInfo>() {
 				public int compare(ThreadInfo o1, ThreadInfo o2) {
+					
 					long diff = threadBean.getThreadCpuTime(o2.getThreadId())
 							- threadBean.getThreadCpuTime(o1.getThreadId());
 					if (diff == 0) {
@@ -318,9 +318,9 @@ AEThreadMonitor
 			});
 		}
 
-		for (int i = 0; i < threadInfos.length; i++) {
+		for (int i = 0; i < threadInfos.size(); i++) {
 			try {
-				ThreadInfo threadInfo = threadInfos[i];
+				ThreadInfo threadInfo = threadInfos.get(i);
 
 				long lCpuTime = disable_getThreadCpuTime ? -1
 						: threadBean.getThreadCpuTime(threadInfo.getThreadId());
diff --git a/com/aelitis/azureus/core/networkmanager/admin/NetworkAdmin.java b/com/aelitis/azureus/core/networkmanager/admin/NetworkAdmin.java
index a935d53..420a7cd 100644
--- a/com/aelitis/azureus/core/networkmanager/admin/NetworkAdmin.java
+++ b/com/aelitis/azureus/core/networkmanager/admin/NetworkAdmin.java
@@ -23,6 +23,7 @@
 
 package com.aelitis.azureus.core.networkmanager.admin;
 
+import java.io.IOException;
 import java.net.InetAddress;
 import java.nio.channels.UnsupportedAddressTypeException;
 
@@ -94,6 +95,12 @@ NetworkAdmin
 	public abstract InetAddress[]
 	getBindableAddresses();
 	
+	public abstract int
+	getBindablePort(
+		int		preferred_port )
+	
+		throws IOException;
+	
 	public abstract NetworkAdminNetworkInterface[]
 	getInterfaces();
 	
@@ -189,6 +196,8 @@ NetworkAdmin
 	public abstract InetAddress
 	getDefaultPublicAddress();
 	
+	public abstract InetAddress getDefaultPublicAddressV6();
+	
 	public abstract void
 	addPropertyChangeListener(
 		NetworkAdminPropertyChangeListener	listener );
diff --git a/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminImpl.java b/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminImpl.java
index 3e076e9..99acc9e 100644
--- a/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminImpl.java
@@ -23,6 +23,7 @@
 
 package com.aelitis.azureus.core.networkmanager.admin.impl;
 
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.*;
 import java.nio.channels.ServerSocketChannel;
@@ -32,9 +33,15 @@ import java.util.regex.Pattern;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
-import org.gudy.azureus2.core3.logging.*;
+import org.gudy.azureus2.core3.logging.LogAlert;
+import org.gudy.azureus2.core3.logging.LogEvent;
+import org.gudy.azureus2.core3.logging.LogIDs;
+import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.platform.*;
+import org.gudy.azureus2.platform.PlatformManager;
+import org.gudy.azureus2.platform.PlatformManagerCapabilities;
+import org.gudy.azureus2.platform.PlatformManagerFactory;
+import org.gudy.azureus2.platform.PlatformManagerPingCallback;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.platform.PlatformManagerException;
 import org.gudy.azureus2.plugins.utils.Utilities;
@@ -42,7 +49,10 @@ import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.instancemanager.*;
+import com.aelitis.azureus.core.instancemanager.AZInstance;
+import com.aelitis.azureus.core.instancemanager.AZInstanceManager;
+import com.aelitis.azureus.core.instancemanager.AZInstanceManagerListener;
+import com.aelitis.azureus.core.instancemanager.AZInstanceTracked;
 import com.aelitis.azureus.core.networkmanager.admin.*;
 import com.aelitis.azureus.core.networkmanager.impl.http.HTTPNetworkManager;
 import com.aelitis.azureus.core.networkmanager.impl.tcp.TCPNetworkManager;
@@ -62,7 +72,7 @@ NetworkAdminImpl
 	
 	private static final boolean	FULL_INTF_PROBE	= false;
 	
-	private Set							old_network_interfaces;
+	private Set<NetworkInterface>			old_network_interfaces;
 	private InetAddress[]				currentBindIPs			= new InetAddress[] { null };
 	private boolean						supportsIPv6withNIO		= true;
 	private boolean						supportsIPv6 = true;
@@ -220,13 +230,13 @@ NetworkAdminImpl
 				boolean newV6 = false;
 				boolean newV4 = false;
 				
-				Set interfaces = old_network_interfaces;
+				Set<NetworkInterface> interfaces = old_network_interfaces;
 				if (interfaces != null)
 				{
-					Iterator it = interfaces.iterator();
+					Iterator<NetworkInterface> it = interfaces.iterator();
 					while (it.hasNext())
 					{
-						NetworkInterface ni = (NetworkInterface) it.next();
+						NetworkInterface ni = it.next();
 						Enumeration addresses = ni.getInetAddresses();
 						while (addresses.hasMoreElements())
 						{
@@ -590,6 +600,82 @@ NetworkAdminImpl
   			}
   		}
   	}
+  	
+	public int
+	getBindablePort(
+		int	prefer_port )
+	
+		throws IOException
+	{
+		final int tries = 1024;
+		
+		Random random = new Random();
+		
+		for ( int i=1;i<=tries;i++ ){
+			
+			int port;
+			
+			if ( i == 1 && prefer_port != 0 ){
+				
+				port = prefer_port;
+				
+			}else{
+				
+				port = i==tries?0:random.nextInt(20000) + 40000;
+			}
+			
+			ServerSocketChannel ssc = null;
+			
+			try{
+				ssc = ServerSocketChannel.open();
+
+				ssc.socket().setReuseAddress( true );
+				
+				bind( ssc, null, port );
+
+				port = ssc.socket().getLocalPort();
+				
+				ssc.close();
+				
+				return( port );
+				
+			}catch( Throwable e ){
+				
+				if ( ssc != null ){
+					
+					try{
+						ssc.close();
+						
+					}catch( Throwable f ){
+						
+						Debug.printStackTrace(e);
+					}
+					
+					ssc = null;
+				}
+			}
+		}
+		
+		throw( new IOException( "No bindable ports found" ));
+	}
+	
+	protected void
+	bind(
+		ServerSocketChannel	ssc,
+		InetAddress			address,
+		int					port )
+	
+		throws IOException
+	{		
+		if ( address == null ){
+			
+			ssc.socket().bind( new InetSocketAddress( port ), 1024 );
+			
+		}else{
+			
+			ssc.socket().bind( new InetSocketAddress( address, port ), 1024 );
+		}
+	}
 	
 	public InetAddress 
 	guessRoutableBindAddress() 
@@ -895,6 +981,32 @@ NetworkAdminImpl
 		return( utils.getPublicAddress( true ));
 	}
 	
+	@Override
+	public InetAddress getDefaultPublicAddressV6() {
+		if(!supportsIPv6)
+			return null;
+		
+		// check bindings first
+		for(InetAddress addr : currentBindIPs)
+		{
+			// found a specific bind address, use that one
+			if(AddressUtils.isGlobalAddressV6(addr))
+				return addr;
+			
+			// found v6 any-local address, check interfaces for a best match
+			if(addr instanceof Inet6Address && addr.isAnyLocalAddress())
+			{
+				ArrayList<InetAddress> addrs = new ArrayList<InetAddress>();
+				for(NetworkInterface iface : old_network_interfaces)
+					addrs.addAll(Collections.list(iface.getInetAddresses()));
+				
+				return AddressUtils.pickBestGlobalV6Address(addrs);
+			}
+		}
+		
+		return null;
+	}
+	
 	protected void
 	firePropertyChange(
 		String	property )
diff --git a/com/aelitis/azureus/core/networkmanager/impl/ByteBucketST.java b/com/aelitis/azureus/core/networkmanager/impl/ByteBucketST.java
index 435cb89..38a89cf 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/ByteBucketST.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/ByteBucketST.java
@@ -55,7 +55,7 @@ ByteBucketST
 	    this.rate = rate_bytes_per_sec;
 	    this.burst_rate = burst_rate;
 	    avail_bytes = 0; //start bucket empty
-	    prev_update_time = SystemTime.getCurrentTime();
+	    prev_update_time = SystemTime.getSteppedMonotonousTime();
 	    ensureByteBucketMinBurstRate();
 	  }
 	  
@@ -134,17 +134,13 @@ ByteBucketST
 	  
 	  
 	  private void update_avail_byte_count() {
-	      final long now =SystemTime.getCurrentTime();
+	      final long now =SystemTime.getSteppedMonotonousTime();
 	      if (prev_update_time <now) {
 	          avail_bytes +=((now -prev_update_time) * rate) / 1000;
 	          prev_update_time =now;
 	          if( avail_bytes > burst_rate ) avail_bytes = burst_rate;
 	          else if( avail_bytes < 0 )  Debug.out("ERROR: avail_bytes < 0: " + avail_bytes);
 	      }
-	      else if (prev_update_time >now) {	//oops, time went backwards
-	          avail_bytes =burst_rate;
-	          prev_update_time =now;
-	      }
 	  }
 
 	  
diff --git a/com/aelitis/azureus/core/networkmanager/impl/tcp/VirtualChannelSelectorImpl.java b/com/aelitis/azureus/core/networkmanager/impl/tcp/VirtualChannelSelectorImpl.java
index 3457109..4fa969f 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/tcp/VirtualChannelSelectorImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/tcp/VirtualChannelSelectorImpl.java
@@ -57,7 +57,7 @@ public class VirtualChannelSelectorImpl {
 		
 			// hack for 10.6 - will switch to not doing System.setProperty( "java.nio.preferSelect", "true" ); later
 		
-		boolean	is_osx_16	= false;
+			//boolean	is_osx_16	= false;
 		
 		try{
 				// unfortunately the package maintainer has set os.name to Linux for FreeBSD...
@@ -91,6 +91,7 @@ public class VirtualChannelSelectorImpl {
 						is_freebsd_7_or_higher = Integer.parseInt(digits) >= 7;
 					}	
 				}
+			/*
 			}else if ( Constants.isOSX ){
 				
 				String os_version = System.getProperty( "os.version", "" );
@@ -99,17 +100,18 @@ public class VirtualChannelSelectorImpl {
 					
 					is_osx_16 = true;
 				}
+			*/
 			}
 		}catch( Throwable e ){
 			
 			e.printStackTrace();
 		}
 			
-		MAYBE_BROKEN_SELECT = is_freebsd_7_or_higher || is_diablo || is_osx_16;
+		MAYBE_BROKEN_SELECT = is_freebsd_7_or_higher || is_diablo; // || is_osx_16;
 		
 		if ( MAYBE_BROKEN_SELECT ){
 			
-			System.out.println( "Enabling broken select detection: diablo=" + is_diablo + ", freebsd 7+=" + is_freebsd_7_or_higher + ", osx 10.6=" + is_osx_16 );
+			System.out.println( "Enabling broken select detection: diablo=" + is_diablo + ", freebsd 7+=" + is_freebsd_7_or_higher ); //  + ", osx 10.6=" + is_osx_16 );
 
 		}
 	}
diff --git a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionManager.java b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionManager.java
index ca759ba..7e2c6ba 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionManager.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionManager.java
@@ -170,7 +170,7 @@ UDPConnectionManager
 	    					ProtocolDecoder	decoder,
 	    					ByteBuffer		remaining_initial_data )
 	    				{
-	    					synchronized( this ){
+	    					synchronized( UDPConnectionManager.this ){
 	    						
 	    						if ( outbound_connection_count > 0 ){
 
@@ -214,7 +214,7 @@ UDPConnectionManager
 	    				handshakeFailure( 
 	    					Throwable failure_msg )
 	    				{
-	    					synchronized( this ){
+	    					synchronized( UDPConnectionManager.this ){
 	    						
 	    						if ( outbound_connection_count > 0 ){
 
@@ -520,44 +520,51 @@ UDPConnectionManager
 		}
 	}
 	
-	protected synchronized boolean
+	protected boolean
 	rateLimitIncoming(
 		InetSocketAddress	s_address )
 	{
-		byte[]	address = s_address.getAddress().getAddress();
-		
-		int	hit_count = incoming_bloom.add( address );
-		
 		long	now = SystemTime.getCurrentTime();
 
-			// allow up to 10% bloom filter utilisation
+		byte[]	address = s_address.getAddress().getAddress();
+	
+		long	delay;
 		
-		if ( incoming_bloom.getSize() / incoming_bloom.getEntryCount() < 10 ){
-			
-			incoming_bloom = BloomFilterFactory.createAddRemove4Bit(incoming_bloom.getSize() + BLOOM_INCREASE );
+		synchronized( this ){
 			
-			incoming_bloom_create_time	= now;
-			
-     		Logger.log(	new LogEvent(LOGID, "UDP connnection bloom: size increased to " + incoming_bloom.getSize()));
-
-		}else if ( now < incoming_bloom_create_time || now - incoming_bloom_create_time > BLOOM_RECREATE ){
-			
-			incoming_bloom = BloomFilterFactory.createAddRemove4Bit(incoming_bloom.getSize());
+			int	hit_count = incoming_bloom.add( address );
+				
+				// allow up to 10% bloom filter utilisation
 			
-			incoming_bloom_create_time	= now;
-		}
+			if ( incoming_bloom.getSize() / incoming_bloom.getEntryCount() < 10 ){
+				
+				incoming_bloom = BloomFilterFactory.createAddRemove4Bit(incoming_bloom.getSize() + BLOOM_INCREASE );
+				
+				incoming_bloom_create_time	= now;
+				
+	     		Logger.log(	new LogEvent(LOGID, "UDP connnection bloom: size increased to " + incoming_bloom.getSize()));
+	
+			}else if ( now < incoming_bloom_create_time || now - incoming_bloom_create_time > BLOOM_RECREATE ){
+				
+				incoming_bloom = BloomFilterFactory.createAddRemove4Bit(incoming_bloom.getSize());
+				
+				incoming_bloom_create_time	= now;
+			}
+				
+			if ( hit_count >= 15 ){
+				
+	     		Logger.log(	new LogEvent(LOGID, "UDP incoming: too many recent connection attempts from " + s_address ));
+	     		
+				return( false );
+			}
 			
-		if ( hit_count >= 15 ){
+			long	since_last = now - last_incoming;
+		
+			delay = 100 - since_last;
 			
-     		Logger.log(	new LogEvent(LOGID, "UDP incoming: too many recent connection attempts from " + s_address ));
-     		
-			return( false );
+			last_incoming = now;	
 		}
 		
-		long	since_last = now - last_incoming;
-		
-		long	delay = 100 - since_last;
-		
 			// limit to 10 a second
 		
 		if ( delay > 0 && delay < 100 ){
@@ -569,8 +576,6 @@ UDPConnectionManager
 			}
 		}
 		
-		last_incoming = now;	
-		
 		return( true );
 	}
 	
diff --git a/com/aelitis/azureus/core/pairing/PairedService.java b/com/aelitis/azureus/core/pairing/PairedService.java
new file mode 100644
index 0000000..4bd29c8
--- /dev/null
+++ b/com/aelitis/azureus/core/pairing/PairedService.java
@@ -0,0 +1,35 @@
+/*
+ * Created on Oct 5, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.pairing;
+
+public interface 
+PairedService 
+{
+	public String
+	getSID();
+	
+	public PairingConnectionData
+	getConnectionData();
+	
+	public void
+	remove();
+}
diff --git a/com/aelitis/azureus/core/pairing/PairingConnectionData.java b/com/aelitis/azureus/core/pairing/PairingConnectionData.java
new file mode 100644
index 0000000..611cfdf
--- /dev/null
+++ b/com/aelitis/azureus/core/pairing/PairingConnectionData.java
@@ -0,0 +1,44 @@
+/*
+ * Created on Oct 5, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.pairing;
+
+public interface 
+PairingConnectionData 
+{
+	public static final String ATTR_IP_V4		= "ip4";
+	public static final String ATTR_IP_V6		= "ip6";
+	public static final String ATTR_PORT		= "port";
+	public static final String ATTR_PROTOCOL	= "protocol";
+	public static final String ATTR_HOST		= "host";
+	
+	public void
+	setAttribute(
+		String		name,
+		String		value );
+	
+	public String
+	getAttribute(
+		String		name );
+	
+	public void
+	sync();
+}
diff --git a/com/aelitis/azureus/core/pairing/PairingException.java b/com/aelitis/azureus/core/pairing/PairingException.java
new file mode 100644
index 0000000..297e925
--- /dev/null
+++ b/com/aelitis/azureus/core/pairing/PairingException.java
@@ -0,0 +1,42 @@
+/*
+ * Created on Oct 5, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.pairing;
+
+public class 
+PairingException
+	extends Exception
+{
+	public
+	PairingException(
+		String		str )
+	{
+		super( str );
+	}
+	
+	public
+	PairingException(
+		String		str,
+		Throwable	e )
+	{
+		super( str, e );
+	}
+}
diff --git a/com/aelitis/azureus/core/pairing/PairingManager.java b/com/aelitis/azureus/core/pairing/PairingManager.java
new file mode 100644
index 0000000..2ccaf66
--- /dev/null
+++ b/com/aelitis/azureus/core/pairing/PairingManager.java
@@ -0,0 +1,55 @@
+/*
+ * Created on Oct 5, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.pairing;
+
+public interface 
+PairingManager 
+{
+	public boolean
+	isEnabled();
+	
+	public String
+	getAccessCode()
+	
+		throws PairingException;
+	
+	public String
+	getReplacementAccessCode()
+	
+		throws PairingException;
+	
+	public PairedService
+	addService(
+		String		sid );
+	
+	public PairedService
+	getService(
+		String		sid );
+	
+	public void
+	addListener(
+		PairingManagerListener	l );
+	
+	public void
+	removeListener(
+		PairingManagerListener	l );
+}
diff --git a/com/aelitis/azureus/core/pairing/PairingManagerFactory.java b/com/aelitis/azureus/core/pairing/PairingManagerFactory.java
new file mode 100644
index 0000000..f8689b2
--- /dev/null
+++ b/com/aelitis/azureus/core/pairing/PairingManagerFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Created on Oct 5, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.pairing;
+
+import com.aelitis.azureus.core.pairing.impl.PairingManagerImpl;
+
+public class 
+PairingManagerFactory 
+{
+	public static PairingManager
+	getSingleton()
+	{
+		return( PairingManagerImpl.getSingleton());
+	}
+}
diff --git a/com/aelitis/azureus/core/pairing/PairingManagerListener.java b/com/aelitis/azureus/core/pairing/PairingManagerListener.java
new file mode 100644
index 0000000..6a514f8
--- /dev/null
+++ b/com/aelitis/azureus/core/pairing/PairingManagerListener.java
@@ -0,0 +1,30 @@
+/*
+ * Created on Oct 9, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.pairing;
+
+public interface 
+PairingManagerListener 
+{
+	public void
+	somethingChanged(
+		PairingManager	pm );
+}
diff --git a/com/aelitis/azureus/core/pairing/impl/PairingManagerImpl.java b/com/aelitis/azureus/core/pairing/impl/PairingManagerImpl.java
new file mode 100644
index 0000000..bc14e6b
--- /dev/null
+++ b/com/aelitis/azureus/core/pairing/impl/PairingManagerImpl.java
@@ -0,0 +1,1134 @@
+/*
+ * Created on Oct 5, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.pairing.impl;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.AESemaphore;
+import org.gudy.azureus2.core3.util.AEThread2;
+import org.gudy.azureus2.core3.util.AEVerifier;
+import org.gudy.azureus2.core3.util.AsyncDispatcher;
+import org.gudy.azureus2.core3.util.BDecoder;
+import org.gudy.azureus2.core3.util.BEncoder;
+import org.gudy.azureus2.core3.util.Base32;
+import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.DelayedEvent;
+import org.gudy.azureus2.core3.util.SimpleTimer;
+import org.gudy.azureus2.core3.util.SystemProperties;
+import org.gudy.azureus2.core3.util.SystemTime;
+import org.gudy.azureus2.core3.util.TimerEvent;
+import org.gudy.azureus2.core3.util.TimerEventPerformer;
+import org.gudy.azureus2.core3.util.TimerEventPeriodic;
+import org.gudy.azureus2.core3.util.UrlUtils;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.UIManagerEvent;
+import org.gudy.azureus2.plugins.ui.config.ActionParameter;
+import org.gudy.azureus2.plugins.ui.config.BooleanParameter;
+import org.gudy.azureus2.plugins.ui.config.ConfigSection;
+import org.gudy.azureus2.plugins.ui.config.HyperlinkParameter;
+import org.gudy.azureus2.plugins.ui.config.InfoParameter;
+import org.gudy.azureus2.plugins.ui.config.LabelParameter;
+import org.gudy.azureus2.plugins.ui.config.Parameter;
+import org.gudy.azureus2.plugins.ui.config.ParameterListener;
+import org.gudy.azureus2.plugins.ui.config.StringParameter;
+import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
+import org.gudy.azureus2.plugins.utils.DelayedTask;
+import org.gudy.azureus2.plugins.utils.StaticUtilities;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminHTTPProxy;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminSocksProxy;
+import com.aelitis.azureus.core.pairing.*;
+import com.aelitis.azureus.core.security.CryptoManager;
+import com.aelitis.azureus.core.security.CryptoManagerFactory;
+import com.aelitis.azureus.core.util.CopyOnWriteList;
+import com.aelitis.azureus.plugins.upnp.UPnPPlugin;
+import com.aelitis.azureus.plugins.upnp.UPnPPluginService;
+import com.aelitis.net.upnp.UPnPRootDevice;
+
+public class 
+PairingManagerImpl
+	implements PairingManager
+{
+	private static final boolean DEBUG	= false;
+	
+	private static final String	SERVICE_URL;
+	
+	static{
+		String url = System.getProperty( "az.pairing.url", "" );
+		
+		if ( url.length() == 0 ){
+			
+			SERVICE_URL = Constants.PAIRING_URL;
+			
+		}else{
+			
+			SERVICE_URL = url;
+		}
+	}
+	
+	private static final PairingManagerImpl	singleton = new PairingManagerImpl();
+	
+	public static PairingManager
+	getSingleton()
+	{
+		return( singleton );
+	}
+	
+	private static final int	GLOBAL_UPDATE_PERIOD	= 60*1000;
+	private static final int	CD_REFRESH_PERIOD		= 23*60*60*1000;
+	private static final int	CD_REFRESH_TICKS		= CD_REFRESH_PERIOD / GLOBAL_UPDATE_PERIOD;
+	
+	private AzureusCore	azureus_core;
+	
+	private BooleanParameter 	param_enable;
+
+	
+	private InfoParameter		param_ac_info;
+	private InfoParameter		param_status_info;
+	private HyperlinkParameter	param_view;
+	
+	private BooleanParameter 	param_e_enable;
+	private StringParameter		param_ipv4;
+	private StringParameter		param_ipv6;
+	private StringParameter		param_host;
+	
+	private Map<String,PairedServiceImpl>		services = new HashMap<String, PairedServiceImpl>();
+	
+	private AESemaphore	init_sem = new AESemaphore( "PM:init" );
+	
+	private TimerEventPeriodic	global_update_event;
+	
+	private InetAddress		current_v4;
+	private InetAddress		current_v6;
+	
+	private boolean	update_outstanding;
+	private boolean	updates_enabled;
+
+	private static final int MIN_UPDATE_PERIOD_DEFAULT	= 60*1000;
+	private static final int MAX_UPDATE_PERIOD_DEFAULT	= 60*60*1000;
+		
+	private int min_update_period	= MIN_UPDATE_PERIOD_DEFAULT;
+	private int max_update_period	= MAX_UPDATE_PERIOD_DEFAULT;
+	
+	
+	private AsyncDispatcher	dispatcher = new AsyncDispatcher();
+	
+	private boolean			must_update_once;
+	private TimerEvent		deferred_update_event;
+	private long			last_update_time		= -1;
+	private int				consec_update_fails;
+	
+	private String			last_message;
+	
+	private CopyOnWriteList<PairingManagerListener>	listeners = new CopyOnWriteList<PairingManagerListener>();
+	
+	protected
+	PairingManagerImpl()
+	{
+		must_update_once = COConfigurationManager.getBooleanParameter( "pairing.updateoutstanding" );
+
+		PluginInterface default_pi = PluginInitializer.getDefaultInterface();
+		
+		final UIManager	ui_manager = default_pi.getUIManager();
+		
+		BasicPluginConfigModel configModel = ui_manager.createBasicPluginConfigModel(
+				ConfigSection.SECTION_CONNECTION, "Pairing");
+
+		param_enable = configModel.addBooleanParameter2( "pairing.enable", "pairing.enable", false );
+		
+		String	access_code = readAccessCode();
+		
+		param_ac_info = configModel.addInfoParameter2( "pairing.accesscode", access_code);
+		
+		param_status_info = configModel.addInfoParameter2( "pairing.status.info", "" );
+		
+		param_view = configModel.addHyperlinkParameter2( "pairing.view.registered", SERVICE_URL + "/web/view?ac=" + access_code);
+
+		if ( access_code.length() == 0 ){
+			
+			param_view.setEnabled( false );
+		}
+		
+		final ActionParameter ap = configModel.addActionParameter2( "pairing.ac.getnew", "pairing.ac.getnew.create" );
+		
+		ap.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter 	param ) 
+				{
+					try{
+						ap.setEnabled( false );
+						
+						allocateAccessCode( false );
+						
+						SimpleTimer.addEvent(
+							"PM:enabler",
+							SystemTime.getOffsetTime(30*1000),
+							new TimerEventPerformer()
+							{
+								public void 
+								perform(
+									TimerEvent event ) 
+								{
+									ap.setEnabled( true );
+								}
+							});
+						
+					}catch( Throwable e ){
+						
+						ap.setEnabled( true );
+						
+						String details = MessageText.getString(
+								"pairing.alloc.fail",
+								new String[]{ Debug.getNestedExceptionMessage( e )});
+						
+						ui_manager.showMessageBox(
+								"pairing.op.fail",
+								"!" + details + "!",
+								UIManagerEvent.MT_OK );
+					}
+				}
+			});
+		
+		LabelParameter	param_e_info = configModel.addLabelParameter2( "pairing.explicit.info" );
+		
+		param_e_enable = configModel.addBooleanParameter2( "pairing.explicit.enable", "pairing.explicit.enable", false );
+		
+		param_ipv4	= configModel.addStringParameter2( "pairing.ipv4", "pairing.ipv4", "" );
+		param_ipv6	= configModel.addStringParameter2( "pairing.ipv6", "pairing.ipv6", "" );
+		param_host	= configModel.addStringParameter2( "pairing.host", "pairing.host", "" );
+		
+		param_ipv4.setGenerateIntermediateEvents( false );
+		param_ipv6.setGenerateIntermediateEvents( false );
+		param_host.setGenerateIntermediateEvents( false );
+		
+		ParameterListener change_listener = 
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param )
+				{
+					updateNeeded();
+					
+					if ( param == param_enable ){
+						
+						fireChanged();
+					}
+				}
+			};
+			
+		param_enable.addListener( change_listener );
+		param_e_enable.addListener(	change_listener );
+		param_ipv4.addListener(	change_listener );
+		param_ipv6.addListener(	change_listener );
+		param_host.addListener(	change_listener );
+		
+		param_e_enable.addEnabledOnSelection( param_ipv4 );
+		param_e_enable.addEnabledOnSelection( param_ipv6 );
+		param_e_enable.addEnabledOnSelection( param_host );
+		
+		configModel.createGroup(
+			"pairing.group.explicit",
+			new Parameter[]{
+				param_e_info,
+				param_e_enable,
+				param_ipv4,	
+				param_ipv6,
+				param_host,
+			});
+		
+		AzureusCoreFactory.addCoreRunningListener(
+			new AzureusCoreRunningListener()
+			{
+				public void 
+				azureusCoreRunning(
+					AzureusCore core )
+				{
+					initialise( core );
+				}
+			});
+	}
+	
+	
+	protected void
+	initialise(
+		AzureusCore		_core )
+	{
+		synchronized( this ){
+			
+			azureus_core	= _core;
+		}
+		
+		try{
+			PluginInterface default_pi = PluginInitializer.getDefaultInterface();
+
+			DelayedTask dt = default_pi.getUtilities().createDelayedTask(
+				new Runnable()
+				{
+					public void 
+					run() 
+					{
+						new DelayedEvent( 
+							"PM:delayinit",
+							30*1000,
+							new AERunnable()
+							{
+								public void
+								runSupport()
+								{
+									enableUpdates();
+								}
+							});
+					}
+				});
+			
+			dt.queue();
+			
+		}finally{
+			
+			init_sem.releaseForever();
+		}
+	}
+	
+	protected void
+	waitForInitialisation()
+	
+		throws PairingException
+	{
+		if ( !init_sem.reserve( 30*1000 )){
+		
+			throw( new PairingException( "Timeout waiting for initialisation" ));
+		}
+	}
+	
+	public boolean
+	isEnabled()
+	{
+		return( param_enable.getValue());
+	}
+	
+	protected void
+	setStatus(
+		String		str )
+	{
+		param_status_info.setValue( str );
+	}
+	
+	protected String
+	readAccessCode()
+	{
+		return( COConfigurationManager.getStringParameter( "pairing.accesscode", "" ));
+	}
+	
+	protected void
+	writeAccessCode(
+		String		ac )
+	{
+		COConfigurationManager.setParameter( "pairing.accesscode", ac );
+		 
+		param_ac_info.setValue( ac );
+		 
+		param_view.setHyperlink( SERVICE_URL + "/web/view?ac=" + ac );
+				
+		param_view.setEnabled( ac.length() > 0 );
+	}
+	
+	protected String
+	allocateAccessCode(
+		boolean		updating )
+	
+		throws PairingException
+	{
+		Map<String,Object>	request = new HashMap<String, Object>();
+		
+		String existing = readAccessCode();
+		
+		request.put( "ac", existing );
+		
+		Map<String,Object> response = sendRequest( "allocate", request );
+		
+		try{
+			String code = getString( response, "ac" );
+			
+			writeAccessCode( code );
+				
+			if ( !updating ){
+			
+				updateNeeded();
+			}
+			
+			return( code );
+			
+		}catch( Throwable e ){
+			
+			throw( new PairingException( "allocation failed", e ));
+		}
+	}
+
+	public String
+	getAccessCode()
+	
+		throws PairingException
+	{
+		waitForInitialisation();
+		
+		String ac = readAccessCode();
+		
+		if ( ac == null || ac.length() == 0 ){
+			
+			ac = allocateAccessCode( false );
+		}
+		
+		return( ac );
+	}
+	
+	public String
+	getReplacementAccessCode()
+	
+		throws PairingException
+	{
+		waitForInitialisation();
+		
+		String new_code = allocateAccessCode( false );
+		
+		return( new_code );
+	}
+	
+	public PairedService
+	addService(
+		String		sid )
+	{
+		synchronized( this ){
+						
+			PairedServiceImpl	result = services.get( sid );
+			
+			if ( result == null ){
+				
+				if ( DEBUG ){
+					System.out.println( "PS: added " + sid );
+				}
+				
+				result = new PairedServiceImpl( sid );
+				
+				services.put( sid, result );
+			}
+			
+			return( result );
+		}
+	}
+	
+	public PairedService
+	getService(
+		String		sid )
+	{
+		synchronized( this ){
+			
+			PairedService	result = services.get( sid );
+			
+			return( result );
+		}
+	}
+	
+	protected void
+	remove(
+		PairedServiceImpl	service )
+	{
+		synchronized( this ){
+
+			String sid = service.getSID();
+			
+			if ( services.remove( sid ) != null ){
+				
+				if ( DEBUG ){
+					System.out.println( "PS: removed " + sid );
+				}
+			}
+		}
+		
+		updateNeeded();
+	}
+	
+	protected void
+	sync(
+		PairedServiceImpl	service )
+	{
+		updateNeeded();
+	}
+	
+	protected InetAddress
+	updateAddress(
+		InetAddress		current,
+		InetAddress		latest,
+		boolean			v6 )
+	{
+		if ( v6 ){
+			
+			if ( latest instanceof Inet4Address ){
+				
+				return( current );
+			}
+		}else{
+			
+			if ( latest instanceof Inet6Address ){
+				
+				return( current );
+			}
+		}
+		
+		if ( current == latest ){
+			
+			return( current );
+		}
+		
+		if ( current == null || latest == null ){
+			
+			return( latest );
+		}
+		
+		if ( !current.equals( latest )){
+			
+			return( latest );
+		}
+		
+		return( current );
+	}
+	
+	protected void
+	updateGlobals(
+		boolean	is_updating )	
+	{
+		synchronized( this ){
+						
+			NetworkAdmin network_admin = NetworkAdmin.getSingleton();
+					
+			InetAddress latest_v4 = azureus_core.getInstanceManager().getMyInstance().getExternalAddress();
+			
+			InetAddress temp_v4 = updateAddress( current_v4, latest_v4, false );
+			
+			InetAddress latest_v6 = network_admin.getDefaultPublicAddressV6();
+	
+			InetAddress temp_v6 = updateAddress( current_v6, latest_v6, true );
+	
+			if (	temp_v4 != current_v4 ||
+					temp_v6 != current_v6 ){
+				
+				current_v4	= temp_v4;
+				current_v6	= temp_v6;
+				
+				if ( !is_updating ){
+				
+					updateNeeded();
+				}
+			}
+		}
+	}
+	
+	protected void
+	enableUpdates()
+	{		
+		synchronized( this ){
+			
+			updates_enabled = true;
+
+			if ( update_outstanding ){
+				
+				update_outstanding = false;
+				
+				updateNeeded();
+			}
+		}
+	}
+	
+	protected void
+	updateNeeded()
+	{
+		if ( DEBUG ){
+			System.out.println( "PS: updateNeeded" );
+		}
+		
+		synchronized( this ){
+			
+			if ( updates_enabled ){
+				
+				dispatcher.dispatch(
+					new AERunnable()
+					{
+						public void
+						runSupport()
+						{
+							doUpdate();
+						}
+					});
+						
+				
+			}else{
+				
+				setStatus( MessageText.getString( "pairing.status.initialising" ));
+				
+				update_outstanding	= true;
+			}
+		}
+	}
+	
+	protected void
+	doUpdate()
+	{
+		long	now = SystemTime.getMonotonousTime();
+
+		synchronized( this ){
+			
+			if ( deferred_update_event != null ){
+				
+				return;
+			}
+			
+			long	time_since_last_update = now - last_update_time;
+			
+			if ( last_update_time > 0 &&  time_since_last_update < min_update_period ){
+				
+				deferUpdate(  min_update_period - time_since_last_update  );
+				
+				return;
+			}
+		}
+		
+		try{
+			Map<String,Object>	payload = new HashMap<String, Object>();
+						
+			boolean	is_enabled = param_enable.getValue();
+			
+			synchronized( this ){
+				
+				List<Map<String,String>>	list =  new ArrayList<Map<String,String>>();
+				
+				payload.put( "s", list );
+				
+				if ( services.size() > 0 && is_enabled ){
+					
+					if ( global_update_event == null ){
+						
+						global_update_event = 
+							SimpleTimer.addPeriodicEvent(
+							"PM:updater",
+							GLOBAL_UPDATE_PERIOD,
+							new TimerEventPerformer()
+							{
+								private int	tick_count;
+								
+								public void 
+								perform(
+									TimerEvent event ) 
+								{
+									tick_count++;
+									
+									updateGlobals( false );
+									
+									if ( tick_count % CD_REFRESH_TICKS == 0 ){
+										
+										updateNeeded();
+									}
+								}
+							});
+						
+						updateGlobals( true );
+					}
+					
+					for ( PairedServiceImpl service: services.values()){
+						
+						list.add( service.toMap());
+					}
+				}else{
+					
+						// when we get to zero services we want to push through the
+						// last update to remove cd
+					
+					if ( global_update_event == null ){
+						
+						if ( consec_update_fails == 0 && !must_update_once ){
+					
+							setStatus( MessageText.getString( "pairing.status.disabled" ));
+							
+							return;
+						}
+					}else{
+					
+						global_update_event.cancel();
+					
+						global_update_event = null;
+					}
+				}
+				
+				last_update_time = now;
+			}
+			
+				// we need a valid access code here!
+			
+			String ac = readAccessCode();
+			
+			if ( ac.length() == 0 ){
+				
+				ac = allocateAccessCode( true );			
+			}
+			
+			payload.put( "ac", ac );
+			
+			synchronized( this ){
+
+				if ( current_v4 != null ){
+				
+					payload.put( "c_v4", current_v4.getHostAddress());
+				}
+				
+				if ( current_v6 != null ){
+					
+					payload.put( "c_v6", current_v6.getHostAddress());
+				}
+			
+				if ( param_e_enable.getValue()){
+				
+					String host = param_host.getValue().trim();
+					
+					if ( host.length() > 0 ){
+						
+						payload.put( "e_h", host );
+					}
+					
+					String v4 = param_ipv4.getValue().trim();
+					
+					if ( v4.length() > 0 ){
+						
+						payload.put( "e_v4", v4 );
+					}
+					
+					String v6 = param_ipv6.getValue().trim();
+					
+					if ( v6.length() > 0 ){
+						
+						payload.put( "e_v4", v6 );
+					}
+				}
+				
+					// grab some UPnP info for diagnostics
+				
+				try{
+				    PluginInterface pi_upnp = azureus_core.getPluginManager().getPluginInterfaceByClass( UPnPPlugin.class );
+
+				    if ( pi_upnp != null ){
+				    	
+				        UPnPPlugin upnp = (UPnPPlugin)pi_upnp.getPlugin();
+
+				        if ( upnp.isEnabled()){
+				        	
+				        	List<Map<String,String>>	upnp_list = new ArrayList<Map<String,String>>();
+				        	
+				        	payload.put( "upnp", upnp_list );
+				        	
+				        	UPnPPluginService[] services = upnp.getServices();
+				        	
+				        	Set<UPnPRootDevice> devices = new HashSet<UPnPRootDevice>();
+				        	
+				        	for ( UPnPPluginService service: services ){
+				        		
+				        		UPnPRootDevice root_device = service.getService().getGenericService().getDevice().getRootDevice();
+				        		
+				        		if ( !devices.contains( root_device )){
+				        			
+				        			devices.add( root_device );
+				        	
+					        		Map<String,String>	map = new HashMap<String, String>();
+					        	
+					        		upnp_list.add( map );
+					        		
+					        		map.put( "i", root_device.getInfo());
+				        		}
+				        	}
+				        }
+				    }
+				}catch( Throwable e ){					
+				}
+				
+				try{
+					NetworkAdmin admin = NetworkAdmin.getSingleton();
+					
+					NetworkAdminHTTPProxy http_proxy = admin.getHTTPProxy();
+					
+					if ( http_proxy != null ){
+						
+						payload.put( "hp", http_proxy.getName());
+					}
+					
+					NetworkAdminSocksProxy[] socks_proxies = admin.getSocksProxies();
+					
+					if ( socks_proxies.length > 0 ){
+						
+						payload.put( "sp", socks_proxies[0].getName());
+					}
+				}catch( Throwable e ){	
+				}
+				
+				payload.put( "_enabled", is_enabled?1L:0L );
+			}
+			
+			if ( DEBUG ){
+				System.out.println( "PS: doUpdate: " + payload );
+			}
+			
+			sendRequest( "update", payload );
+			
+			synchronized( this ){
+
+				consec_update_fails	= 0;
+				
+				must_update_once = false;
+				
+				if ( deferred_update_event == null ){
+										
+					COConfigurationManager.setParameter( "pairing.updateoutstanding", false );
+				}
+
+				if ( global_update_event == null ){
+					
+					setStatus( MessageText.getString( "pairing.status.disabled" ));
+					
+				}else{
+					
+					setStatus( 
+						MessageText.getString( 
+							"pairing.status.registered", 
+							new String[]{ new SimpleDateFormat().format(new Date( SystemTime.getCurrentTime() ))}));
+				}
+			}
+		}catch( Throwable e ){
+			
+			synchronized( this ){
+				
+				consec_update_fails++;
+	
+				long back_off = min_update_period;
+				
+				for (int i=0;i<consec_update_fails;i++){
+					
+					back_off *= 2;
+					
+					if ( back_off > max_update_period ){
+					
+						back_off = max_update_period;
+						
+						break;
+					}
+				}
+				
+				deferUpdate( back_off );
+			}
+		}
+	}
+	
+	protected void
+	deferUpdate(
+		long	millis )
+	{
+		millis += 5000;
+		
+		long target = SystemTime.getOffsetTime( millis );
+		
+		setStatus( 
+			MessageText.getString( 
+				"pairing.status.pending", 
+				new String[]{ new SimpleDateFormat().format(new Date( target ))}));
+
+		COConfigurationManager.setParameter( "pairing.updateoutstanding", true );
+		
+		deferred_update_event = 
+			SimpleTimer.addEvent(
+				"PM:defer",
+				target,
+				new TimerEventPerformer()
+				{
+					public void 
+					perform(
+						TimerEvent event )
+					{
+						synchronized( PairingManagerImpl.this ){
+							
+							deferred_update_event = null;
+						}
+						
+						COConfigurationManager.setParameter( "pairing.updateoutstanding", false );
+						
+						updateNeeded();
+					}
+				});
+	}
+	
+	
+	private Map<String, Object> 
+	sendRequest(
+		String 				command,
+		Map<String, Object> payload )
+		
+		throws PairingException
+	{
+		try{
+			Map<String, Object> request = new HashMap<String, Object>();
+
+			CryptoManager cman = CryptoManagerFactory.getSingleton();
+
+			String azid = Base32.encode( cman.getSecureID());
+
+			payload.put( "_azid", azid );
+
+			try{
+				String pk = Base32.encode( cman.getECCHandler().getPublicKey( "pairing" ));
+
+				payload.put( "_pk", pk );
+				
+			}catch( Throwable e ){	
+			}
+			
+			request.put( "req", payload );
+			
+			String request_str = Base32.encode( BEncoder.encode( request ));
+			
+			String other_params = 
+				"&ver=" + UrlUtils.encode( Constants.AZUREUS_VERSION ) + 
+				"&app=" + UrlUtils.encode( SystemProperties.getApplicationName()) +
+				"&locale=" + UrlUtils.encode( MessageText.getCurrentLocale().toString());
+
+			URL target = new URL( SERVICE_URL + "/client/" + command + "?request=" + request_str + other_params );
+			
+			HttpURLConnection connection = (HttpURLConnection)target.openConnection();
+			
+			InputStream is = connection.getInputStream();
+			
+			Map<String,Object> response = (Map<String,Object>)BDecoder.decode( new BufferedInputStream( is ));
+			
+			synchronized( this ){
+				
+				Long	min_retry = (Long)response.get( "min_secs" );
+				
+				if ( min_retry != null ){
+					
+					min_update_period	= min_retry.intValue()*1000;
+				}
+				
+				Long	max_retry = (Long)response.get( "max_secs" );
+				
+				if ( max_retry != null ){
+					
+					max_update_period	= max_retry.intValue()*1000;
+				}
+			}
+			
+			final String message = getString( response, "message" );
+			
+			if ( message != null ){
+				
+				if ( last_message == null || !last_message.equals( message )){
+					
+					last_message = message;
+				
+					try{
+						byte[] message_sig = (byte[])response.get( "message_sig" );
+						
+						AEVerifier.verifyData( message, message_sig );
+						
+						new AEThread2( "PairMsg", true )
+						{
+							public void
+							run()
+							{
+								UIManager ui_manager = StaticUtilities.getUIManager( 120*1000 );
+								
+								if ( ui_manager != null ){
+								
+									ui_manager.showMessageBox(
+											"pairing.server.warning.title",
+											"!" + message + "!",
+											UIManagerEvent.MT_OK );
+								}
+							}
+						}.start();
+						
+					}catch( Throwable e ){
+					}
+				}
+			}
+			
+			String error = getString( response, "error" );
+			
+			if ( error != null ){
+				
+				throw( new PairingException( error ));
+			}
+			
+			return((Map<String,Object>)response.get( "rep" ));
+			
+		}catch( Throwable e ){
+			
+			throw( new PairingException( "invocation failed", e ));
+		}
+	}
+	
+	protected void
+	fireChanged()
+	{
+		for ( PairingManagerListener l: listeners ){
+			
+			try{
+				l.somethingChanged( this );
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+	}
+	
+	public void
+	addListener(
+		PairingManagerListener		l )
+	{
+		listeners.add( l );
+	}
+	
+	public void
+	removeListener(
+		PairingManagerListener		l )
+	{
+		listeners.remove( l );
+	}
+	
+	protected String
+	getString(
+		Map<String,Object>	map,
+		String				name )
+	
+		throws IOException
+	{
+		byte[]	bytes = (byte[])map.get(name);
+		
+		if ( bytes == null ){
+			
+			return( null );
+		}
+		
+		return( new String( bytes, "UTF-8" ));
+	}
+	
+	protected class
+	PairedServiceImpl
+		implements PairedService, PairingConnectionData
+	{
+		private String				sid;
+		private Map<String,String>	attributes	= new HashMap<String, String>();
+		
+		protected
+		PairedServiceImpl(
+			String		_sid )
+		{
+			sid		= _sid;
+		}
+		
+		public String
+		getSID()
+		{
+			return( sid );
+		}
+		
+		public PairingConnectionData
+		getConnectionData()
+		{
+			return( this );
+		}
+		
+		public void
+		remove()
+		{
+			PairingManagerImpl.this.remove( this );
+		}
+		
+		public void
+		setAttribute(
+			String		name,
+			String		value )
+		{
+			synchronized( this ){
+				
+				if ( DEBUG ){
+					System.out.println( "PS: " + sid + ": " + name + " -> " + value );
+				}
+				
+				attributes.put( name, value );
+			}
+		}
+		
+		public String
+		getAttribute(
+			String		name )
+		{
+			return( attributes.get( name ));
+		}
+		
+		public void
+		sync()
+		{
+			PairingManagerImpl.this.sync( this );
+		}
+		
+		protected Map<String,String>
+		toMap()
+		{
+			Map<String,String> result = new HashMap<String, String>();
+			
+			result.put( "sid", sid );
+			
+			synchronized( this ){
+			
+				result.putAll( attributes );
+			}
+			
+			return( result );
+		}
+	}
+}
diff --git a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZHandshake.java b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZHandshake.java
index 841e8d7..781ab35 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZHandshake.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZHandshake.java
@@ -22,9 +22,13 @@
 
 package com.aelitis.azureus.core.peermanager.messaging.azureus;
 
+import java.net.InetAddress;
 import java.util.*;
 
-import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.core3.util.ByteFormatter;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
+import org.gudy.azureus2.core3.util.HashWrapper;
 
 import com.aelitis.azureus.core.peermanager.messaging.Message;
 import com.aelitis.azureus.core.peermanager.messaging.MessageException;
@@ -59,6 +63,7 @@ public class AZHandshake implements AZMessage {
   private int udp_non_data_port;
   private final int handshake_type;
   private final boolean uploadOnly;
+  private final InetAddress ipv6;
   
   
   public AZHandshake( byte[] peer_identity,
@@ -69,6 +74,7 @@ public class AZHandshake implements AZMessage {
                       int tcp_listen_port,
                       int udp_listen_port,
                       int udp_non_data_listen_port,
+                      InetAddress ipv6addr,
                       String[] avail_msg_ids,
                       byte[] avail_msg_versions,
                       int _handshake_type,
@@ -88,6 +94,7 @@ public class AZHandshake implements AZMessage {
     this.handshake_type = _handshake_type;
     this.version = _version;
     this.uploadOnly = uploadOnly;
+    this.ipv6 = ipv6addr;
     
     //verify given port info is ok
     if( tcp_port < 0 || tcp_port > 65535 ) {
@@ -125,6 +132,7 @@ public class AZHandshake implements AZMessage {
   public int getTCPListenPort() {  return tcp_port;  }
   public int getUDPListenPort() {  return udp_port;  }
   public int getUDPNonDataListenPort() {  return udp_non_data_port;  }
+  public InetAddress getIPv6() { return ipv6; }
   
   public int getHandshakeType() {  return handshake_type;  }
   
@@ -154,6 +162,7 @@ public class AZHandshake implements AZMessage {
       							client+ " " +client_version+ ", TCP/UDP ports " +tcp_port+ "/" +udp_port+ "/" + udp_non_data_port +
       							", handshake " + (getHandshakeType() == HANDSHAKE_TYPE_PLAIN ? "plain" : "crypto") +
       							", upload_only = " + (isUploadOnly() ? "1" : "0") + 
+      							(ipv6 != null ? ", ipv6 = "+ipv6.getHostAddress() : "") +
       							(sessionID != null ? ", sessionID: "+sessionID.toBase32String() : "") +
       							(reconnectID != null ? ", reconnect request: "+reconnectID.toBase32String() : "") +
       							"] supports " +msgs_desc;
@@ -179,6 +188,8 @@ public class AZHandshake implements AZMessage {
 			payload_map.put("udp2_port", new Long(udp_non_data_port));
 			payload_map.put("handshake_type", new Long(handshake_type));
 			payload_map.put("upload_only", new Long(uploadOnly ? 1L : 0L));
+			if(ipv6 != null)
+				payload_map.put("ipv6", ipv6.getAddress());
 
 			//available message list
 			List message_list = new ArrayList();
@@ -246,6 +257,18 @@ public class AZHandshake implements AZMessage {
     if( h_type == null ) {  //only 2307+ send type
     	h_type = new Long( HANDSHAKE_TYPE_PLAIN );
     }
+    
+    InetAddress ipv6 = null;
+    if(root.get("ipv6") instanceof byte[])
+	{
+		try
+		{
+			InetAddress.getByAddress((byte[]) root.get("ipv6"));
+		} catch (Exception e)
+		{
+			
+		}
+	}
 
     List raw_msgs = (List) root.get("messages");
     if (raw_msgs == null)  throw new MessageException("raw_msgs == null");
@@ -274,7 +297,7 @@ public class AZHandshake implements AZMessage {
     Long ulOnly = (Long)root.get("upload_only");
     boolean uploadOnly = ulOnly != null && ulOnly.longValue() > 0L ? true : false;
 
-    return new AZHandshake( id, session == null ? null : new HashWrapper(session),reconnect == null ? null : new HashWrapper(reconnect), name, client_version, tcp_lport.intValue(), udp_lport.intValue(), udp2_lport.intValue(), ids, vers, h_type.intValue(), version , uploadOnly);
+    return new AZHandshake( id, session == null ? null : new HashWrapper(session),reconnect == null ? null : new HashWrapper(reconnect), name, client_version, tcp_lport.intValue(), udp_lport.intValue(), udp2_lport.intValue(), ipv6 ,ids, vers, h_type.intValue(), version , uploadOnly);
   }
   
   
diff --git a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageFactory.java b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageFactory.java
index b164b64..3a3a3d4 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageFactory.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageFactory.java
@@ -22,13 +22,17 @@
 
 package com.aelitis.azureus.core.peermanager.messaging.azureus;
 
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
 
-import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
+import org.gudy.azureus2.core3.util.DirectByteBufferPool;
 
 import com.aelitis.azureus.core.networkmanager.RawMessage;
 import com.aelitis.azureus.core.networkmanager.impl.RawMessageImpl;
-import com.aelitis.azureus.core.peermanager.messaging.*;
+import com.aelitis.azureus.core.peermanager.messaging.Message;
+import com.aelitis.azureus.core.peermanager.messaging.MessageException;
+import com.aelitis.azureus.core.peermanager.messaging.MessageManager;
 import com.aelitis.azureus.core.peermanager.messaging.bittorrent.*;
 
 
@@ -73,7 +77,7 @@ public class AZMessageFactory {
    */
   public static void init() {
     try {
-      MessageManager.getSingleton().registerMessageType( new AZHandshake( new byte[20], null, null, "", "", 0, 0, 0, new String[0], new byte[0], 0, MESSAGE_VERSION_SUPPORTS_PADDING,false ) );
+      MessageManager.getSingleton().registerMessageType( new AZHandshake( new byte[20], null, null, "", "", 0, 0, 0, null, new String[0], new byte[0], 0, MESSAGE_VERSION_SUPPORTS_PADDING,false ) );
       MessageManager.getSingleton().registerMessageType( new AZPeerExchange( new byte[20], null, null, MESSAGE_VERSION_SUPPORTS_PADDING ));
       MessageManager.getSingleton().registerMessageType( new AZRequestHint( -1, -1, -1, -1, MESSAGE_VERSION_SUPPORTS_PADDING ));
       MessageManager.getSingleton().registerMessageType( new AZHave( new int[0], MESSAGE_VERSION_SUPPORTS_PADDING ));
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTHandshake.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTHandshake.java
index f5c254c..b338e98 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTHandshake.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTHandshake.java
@@ -1,13 +1,11 @@
 package com.aelitis.azureus.core.peermanager.messaging.bittorrent.ltep;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.Collections;
 import java.util.Map;
 
-import org.gudy.azureus2.core3.util.BEncoder;
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.DirectByteBuffer;
-import org.gudy.azureus2.core3.util.DirectByteBufferPool;
+import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.peermanager.messaging.Message;
 import com.aelitis.azureus.core.peermanager.messaging.MessageException;
@@ -111,6 +109,23 @@ public class LTHandshake implements LTMessage {
 		return ulOnly != null && ulOnly.longValue() > 0L;
 	}
 	
+	public InetAddress getIPv6() {
+		byte[] addr = (byte[])data_dict.get("ipv6");
+		if(addr != null && addr.length == 16)
+		{
+			try
+			{
+				return InetAddress.getByAddress(addr);
+			} catch (UnknownHostException e)
+			{
+				// should not happen
+				e.printStackTrace();
+			}
+		}
+		
+		return null;
+	}
+	
 	public int getTCPListeningPort()
 	{
 		Long port = (Long)data_dict.get("p");
diff --git a/com/aelitis/azureus/core/peermanager/piecepicker/impl/PiecePickerImpl.java b/com/aelitis/azureus/core/peermanager/piecepicker/impl/PiecePickerImpl.java
index a222443..59d19a4 100644
--- a/com/aelitis/azureus/core/peermanager/piecepicker/impl/PiecePickerImpl.java
+++ b/com/aelitis/azureus/core/peermanager/piecepicker/impl/PiecePickerImpl.java
@@ -28,6 +28,7 @@ import org.gudy.azureus2.core3.config.*;
 import org.gudy.azureus2.core3.disk.*;
 import org.gudy.azureus2.core3.disk.impl.DiskManagerFileInfoImpl;
 import org.gudy.azureus2.core3.disk.impl.piecemapper.DMPieceList;
+import org.gudy.azureus2.core3.disk.impl.piecemapper.DMPieceMap;
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.core3.peer.*;
 import org.gudy.azureus2.core3.peer.impl.*;
@@ -1031,6 +1032,7 @@ implements PiecePicker
 		final boolean firstPiecePriorityL =firstPiecePriority;
 		final boolean completionPriorityL =completionPriority;
 
+		final DMPieceMap	pieceMap = diskManager.getPieceMap();
 		try
 		{
 			final boolean rarestOverride = calcRarestAllowed() < 1;
@@ -1042,10 +1044,9 @@ implements PiecePicker
 				if (dmPiece.isDone())
 					continue;	// nothing to do for pieces not needing requesting
 
-				int priority =Integer.MIN_VALUE;
 				int startPriority =Integer.MIN_VALUE;
 
-				final DMPieceList pieceList =diskManager.getPieceList(dmPiece.getPieceNumber());
+				final DMPieceList pieceList =pieceMap.getPieceList(dmPiece.getPieceNumber());
 				final int pieceListSize =pieceList.size();
 				for (int j =0; j <pieceListSize; j++)
 				{
@@ -1054,7 +1055,7 @@ implements PiecePicker
 					final long length =fileInfo.getLength();
 					if (length >0 &&downloaded <length &&!fileInfo.isSkipped())
 					{
-						priority =0;
+						int priority =0;
 						// user option "prioritize first and last piece"
 						// TODO: should prioritize ~10% from edges of file
 						if (firstPiecePriorityL &&fileInfo.getNbPieces() >FIRST_PIECE_MIN_NB)
diff --git a/com/aelitis/azureus/core/peermanager/unchoker/UnchokerUtilTest.java b/com/aelitis/azureus/core/peermanager/unchoker/UnchokerUtilTest.java
index b40d6ee..37a0179 100644
--- a/com/aelitis/azureus/core/peermanager/unchoker/UnchokerUtilTest.java
+++ b/com/aelitis/azureus/core/peermanager/unchoker/UnchokerUtilTest.java
@@ -22,9 +22,13 @@
 
 package com.aelitis.azureus.core.peermanager.unchoker;
 
+import java.net.InetAddress;
 import java.util.*;
 
-import org.gudy.azureus2.core3.peer.*;
+import org.gudy.azureus2.core3.peer.PEPeer;
+import org.gudy.azureus2.core3.peer.PEPeerListener;
+import org.gudy.azureus2.core3.peer.PEPeerManager;
+import org.gudy.azureus2.core3.peer.PEPeerStats;
 import org.gudy.azureus2.core3.util.RandomUtils;
 import org.gudy.azureus2.plugins.network.Connection;
 
@@ -108,6 +112,7 @@ public class UnchokerUtilTest {
       
       final PEPeerStats[] f_stats = { null };
       final PEPeer peer = new PEPeer() {
+    	public InetAddress getAlternativeIPv6() { return null; }
         public void addListener( PEPeerListener listener ){}
         public void removeListener( PEPeerListener listener ){}
         public int getPeerState(){  return PEPeer.TRANSFERING;  }
diff --git a/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderDefinitions.java b/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderDefinitions.java
index f9affdc..4a5b674 100644
--- a/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderDefinitions.java
+++ b/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderDefinitions.java
@@ -274,6 +274,7 @@ public class BTPeerIDByteDecoderDefinitions {
 		addAzStyle("MT", "MoonlightTorrent");
 		addAzStyle("NE", "BT Next Evolution", VER_AZ_THREE_DIGITS);
 		addAzStyle("NX", "Net Transport");
+		addAzStyle("OS", "OneSwarm", VER_AZ_FOUR_DIGITS);
 		addAzStyle("OT", "OmegaTorrent");
 		addAzStyle("PC", PeerClassifier.CACHE_LOGIC, "12.3-4" );
 		addAzStyle("PD", "Pando");
@@ -282,9 +283,13 @@ public class BTPeerIDByteDecoderDefinitions {
 		addAzStyle("qB", "qBittorrent", VER_AZ_THREE_DIGITS);
 		addAzStyle("QD", "qqdownload");
 		addAzStyle("RT", "Retriever");
+		addAzStyle("RZ", "RezTorrent");
 		addAzStyle("S~", "Shareaza alpha/beta");
 		addAzStyle("SB", "SwiftBit");
+		addAzStyle("SD", "\u8FC5\u96F7\u5728\u7EBF (Xunlei)"); // Apparently, the English name of the client is "Thunderbolt".
+		addAzStyle("SG", "GS Torrent", VER_AZ_FOUR_DIGITS);
 		addAzStyle("SN", "ShareNET");
+		addAzStyle("SP", "BitSpirit"); // >= 3.6
 		addAzStyle("SS", "SwarmScope");
 		addAzStyle("ST", "SymTorrent", "2.34");
 		addAzStyle("st", "SharkTorrent");
@@ -297,11 +302,12 @@ public class BTPeerIDByteDecoderDefinitions {
 		addAzStyle("UT", "\u00B5Torrent", VER_AZ_THREE_DIGITS_PLUS_MNEMONIC);
 		addAzStyle("UM", "\u00B5Torrent Mac", VER_AZ_THREE_DIGITS_PLUS_MNEMONIC);
 		addAzStyle("WT", "Bitlet");
-		addAzStyle("WY", "Wyzo");
+		addAzStyle("WY", "FireTorrent"); // formerly Wyzo.
 		addAzStyle("VG", "\u54c7\u560E (Vagaa)", VER_AZ_FOUR_DIGITS);
 		addAzStyle("XL", "\u8FC5\u96F7\u5728\u7EBF (Xunlei)"); // Apparently, the English name of the client is "Thunderbolt".
 		addAzStyle("XT", "XanTorrent");
-		addAzStyle("XX", "XTorrent", "v1234");
+		addAzStyle("XX", "XTorrent", "1.2.34");
+		addAzStyle("XC", "XTorrent", "1.2.34");
 		addAzStyle("ZT", "ZipTorrent"); 
 		
 		addShadowStyle('A', "ABC");
diff --git a/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderUtils.java b/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderUtils.java
index 64e7844..91817c6 100644
--- a/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderUtils.java
+++ b/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderUtils.java
@@ -95,6 +95,7 @@ class BTPeerIDByteDecoderUtils {
 		if (peer_id.substring(1, 3).equals("LH")) {return true;}
 		if (peer_id.substring(1, 3).equals("NE")) {return true;}
 		if (peer_id.substring(1, 3).equals("KT")) {return true;}
+		if (peer_id.substring(1, 3).equals("SP")) {return true;}
 		return false;
 	}
 	
diff --git a/com/aelitis/azureus/core/rssgen/RSSGeneratorPlugin.java b/com/aelitis/azureus/core/rssgen/RSSGeneratorPlugin.java
new file mode 100644
index 0000000..cedd134
--- /dev/null
+++ b/com/aelitis/azureus/core/rssgen/RSSGeneratorPlugin.java
@@ -0,0 +1,257 @@
+/*
+ * Created on Oct 9, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.rssgen;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.URLEncoder;
+import java.util.*;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.util.SystemProperties;
+import org.gudy.azureus2.plugins.PluginException;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageGenerator;
+import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageRequest;
+import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageResponse;
+import org.gudy.azureus2.plugins.ui.config.ConfigSection;
+import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
+import org.gudy.azureus2.ui.webplugin.WebPlugin;
+
+
+public class 
+RSSGeneratorPlugin
+	extends WebPlugin
+{
+	public static final String	PLUGIN_NAME		= "Internal RSS";
+	public static final int 	DEFAULT_PORT    = 6905;
+	public static final String	DEFAULT_ACCESS	= "all";
+	
+	private static volatile RSSGeneratorPlugin		singleton;
+	
+	private static boolean	loaded;
+	
+	private static Properties defaults = new Properties();
+	    
+	public static void
+	load(
+		PluginInterface		plugin_interface )
+	{
+		synchronized( RSSGeneratorPlugin.class ){
+			
+			if ( loaded ){
+				
+				return;
+			}
+			
+			loaded = true;
+		}
+		
+		plugin_interface.getPluginProperties().setProperty( "plugin.version", 	"1.0" );
+		plugin_interface.getPluginProperties().setProperty( "plugin.name", 		PLUGIN_NAME );
+		
+		File	root_dir = new File( SystemProperties.getUserPath() + "rss" );
+		
+		if ( !root_dir.exists()){
+			
+			root_dir.mkdir();
+		}
+		
+		Integer	rss_port;
+		String	rss_access;
+		
+		if ( 	COConfigurationManager.getBooleanParameter( "rss.internal.migrated", false ) ||
+				!COConfigurationManager.getBooleanParameter( "Plugin.default.device.rss.enable", false )){
+			
+			rss_port 	= COConfigurationManager.getIntParameter( "rss.internal.config.port", DEFAULT_PORT );
+			rss_access 	= COConfigurationManager.getStringParameter( "rss.internal.config.access", DEFAULT_ACCESS );
+			
+		}else{
+			
+				// migrate from when the RSS feed was tied to devices
+			
+			int		port 	= COConfigurationManager.getIntParameter( "Plugin.default.device.rss.port", DEFAULT_PORT );
+			
+			rss_port 	= port;
+
+			if ( port != DEFAULT_PORT ){
+				
+				COConfigurationManager.setParameter( "rss.internal.config.port", port );
+			}
+			
+			boolean	local 	= COConfigurationManager.getBooleanParameter( "Plugin.default.device.rss.localonly", true );
+			
+			rss_access	= local?"local":"all";
+			
+			if ( !rss_access.equals( DEFAULT_ACCESS )){
+				
+				COConfigurationManager.setParameter( "rss.internal.config.access", rss_access );
+			}
+			
+			COConfigurationManager.setParameter( "rss.internal.migrated", true );	
+		}
+		
+		defaults.put( WebPlugin.PR_DISABLABLE, new Boolean( true ));
+	    defaults.put( WebPlugin.PR_PORT, rss_port );
+	    defaults.put( WebPlugin.PR_ACCESS, rss_access );
+	    defaults.put( WebPlugin.PR_ROOT_DIR, root_dir.getAbsolutePath());
+	    defaults.put( WebPlugin.PR_ENABLE_KEEP_ALIVE, new Boolean(true));
+	    defaults.put( WebPlugin.PR_HIDE_RESOURCE_CONFIG, new Boolean(true));
+	    defaults.put( WebPlugin.PR_PAIRING_SID, "rss" );
+
+	    BasicPluginConfigModel config = 
+	    	plugin_interface.getUIManager().createBasicPluginConfigModel(
+	    		ConfigSection.SECTION_ROOT, "rss" );
+	    
+	    defaults.put( WebPlugin.PR_CONFIG_MODEL, config );
+	}
+	
+	public static RSSGeneratorPlugin
+	getSingleton()
+	{
+		return( singleton );
+	}
+	
+	
+	private Map<String,Provider>	providers = new TreeMap<String, Provider>();
+	
+	public
+	RSSGeneratorPlugin()
+	{
+		super( defaults );		
+	}
+	
+	public String
+	getURL()
+	{
+		return( getProtocol() + "://127.0.0.1:" + getPort() + "/" );
+	}
+	
+	public void
+	registerProvider(
+		String				name,
+		Provider			provider )
+	{
+		synchronized( providers ){
+		
+			providers.put( name, provider );
+		}
+	}
+	
+	public void
+	initialize(
+		PluginInterface		pi )
+	
+		throws PluginException
+	{
+		singleton = this;
+
+		pi.getPluginProperties().setProperty( "plugin.name", PLUGIN_NAME );
+		
+		super.initialize( pi );
+	}
+	
+	public boolean
+	generateSupport(
+		TrackerWebPageRequest		request,
+		TrackerWebPageResponse		response )
+	
+		throws IOException
+	{
+		String url = request.getURL();
+		
+		if ( url.startsWith( "/" )){
+			
+			url = url.substring( 1 );
+		}
+	
+		if ( url.length() == 0 ){
+			
+			response.setContentType( "text/html; charset=UTF-8" );
+			
+			PrintWriter pw = new PrintWriter(new OutputStreamWriter( response.getOutputStream(), "UTF-8" ));
+
+			pw.println( "<HTML><HEAD><TITLE>Vuze Feeds etc.</TITLE></HEAD><BODY>" );
+			
+			synchronized( providers ){
+				
+				for ( Map.Entry<String,Provider> entry: providers.entrySet()){
+			
+					Provider provider = entry.getValue();
+					
+					if ( !provider.isEnabled()){
+						
+						continue;
+					}
+
+					String	name = entry.getKey();
+								
+					pw.println( "<LI><A href=\"" + URLEncoder.encode( name, "UTF-8" ) + "\">" + name + "</A></LI>" );
+				}
+			}
+			
+			pw.println( "</BODY></HTML>" );
+			
+			pw.flush();
+			
+			return( true );
+			
+		}else{
+			
+			int	pos = url.indexOf( '/' );
+			
+			if ( pos != -1 ){
+				
+				url = url.substring( 0, pos );
+			}
+			
+			Provider provider;
+			
+			synchronized( providers ){
+				
+				provider = providers.get( url );
+			}
+			
+			if ( provider != null && provider.isEnabled()){
+				
+				if ( provider.generate(request, response)){
+					
+					return( true );
+				}
+			}
+		}
+		
+		response.setReplyStatus( 404 );
+		
+		return( true );
+	}
+	
+	public interface
+	Provider
+		extends TrackerWebPageGenerator
+	{
+		public boolean
+		isEnabled();
+	}
+}
diff --git a/com/aelitis/azureus/core/security/impl/CryptoHandlerECC.java b/com/aelitis/azureus/core/security/impl/CryptoHandlerECC.java
index b374985..d79862e 100644
--- a/com/aelitis/azureus/core/security/impl/CryptoHandlerECC.java
+++ b/com/aelitis/azureus/core/security/impl/CryptoHandlerECC.java
@@ -22,38 +22,27 @@
 
 package com.aelitis.azureus.core.security.impl;
 
-import java.math.BigInteger;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.Key;
-import java.security.KeyFactory;
 import java.security.KeyPair;
-import java.security.KeyPairGenerator;
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.SecureRandom;
 import java.security.Signature;
 import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.KeySpec;
 import java.util.Arrays;
 
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
 import javax.crypto.IllegalBlockSizeException;
 
-import org.bouncycastle.jce.ECNamedCurveTable;
-import org.bouncycastle.jce.interfaces.ECPrivateKey;
-import org.bouncycastle.jce.interfaces.ECPublicKey;
 import org.bouncycastle.jce.provider.JCEIESCipher;
-import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
-import org.bouncycastle.jce.spec.ECParameterSpec;
-import org.bouncycastle.jce.spec.ECPrivateKeySpec;
-import org.bouncycastle.jce.spec.ECPublicKeySpec;
 import org.bouncycastle.jce.spec.IEKeySpec;
 import org.bouncycastle.jce.spec.IESParameterSpec;
-import org.bouncycastle.math.ec.ECPoint;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.util.Base32;
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.RandomUtils;
 import org.gudy.azureus2.core3.util.SystemTime;
 
@@ -69,6 +58,10 @@ public class
 CryptoHandlerECC
 	implements CryptoHandler
 {	
+	private static final String	DEFAULT_PASSWORD	= "";
+	private static final Long	DEFAULT_TIMEOUT		= Long.MAX_VALUE;
+	
+
 	private static final int	TIMEOUT_DEFAULT_SECS		= 60*60;
 
 	
@@ -89,6 +82,32 @@ CryptoHandlerECC
 		manager	= _manager;
 		
 		CONFIG_PREFIX += _instance_id + ".";
+		
+			// migration away from system managed keys
+				
+		if ( getDefaultPasswordHandlerType() != CryptoManagerPasswordHandler.HANDLER_TYPE_USER ){
+		
+			COConfigurationManager.setParameter( CONFIG_PREFIX + "default_pwtype", CryptoManagerPasswordHandler.HANDLER_TYPE_USER );
+		}
+		
+		if ( 	getCurrentPasswordType() == CryptoManagerPasswordHandler.HANDLER_TYPE_SYSTEM || 
+				COConfigurationManager.getByteParameter( CONFIG_PREFIX + "publickey", null ) == null ){
+			
+			try{
+				createAndStoreKeys(
+					manager.setPassword(
+						CryptoManager.HANDLER_ECC,
+						CryptoManagerPasswordHandler.HANDLER_TYPE_USER,
+						DEFAULT_PASSWORD.toCharArray(),
+						DEFAULT_TIMEOUT ));
+				
+				Debug.outNoStack( "Successfully migrated key management" );
+				
+			}catch( Throwable e ){
+				
+				Debug.out( "Failed to migrate key management", e );
+			}
+		}
 	}
 	
 	public int
@@ -651,19 +670,28 @@ CryptoHandlerECC
 	}
 	
 	protected Key[]
+  	createAndStoreKeys(
+  		String		reason )
+  	
+  		throws CryptoManagerException
+  	{	
+		CryptoManagerImpl.passwordDetails password_details = 
+				manager.getPassword( 
+  							CryptoManager.HANDLER_ECC,
+  							CryptoManagerPasswordHandler.ACTION_ENCRYPT,
+  							reason,
+  							null,
+  							getDefaultPasswordHandlerType());
+		
+		return( createAndStoreKeys( password_details ));
+  	}
+	
+	protected Key[]
 	createAndStoreKeys(
-		String		reason )
+		CryptoManagerImpl.passwordDetails	password_details )
 	
 		throws CryptoManagerException
 	{		
-		CryptoManagerImpl.passwordDetails password_details = 
-			manager.getPassword( 
-							CryptoManager.HANDLER_ECC,
-							CryptoManagerPasswordHandler.ACTION_ENCRYPT,
-							reason,
-							null,
-							getDefaultPasswordHandlerType());
-		
 		try{
 			synchronized( this ){
 				
diff --git a/com/aelitis/azureus/core/security/impl/CryptoManagerImpl.java b/com/aelitis/azureus/core/security/impl/CryptoManagerImpl.java
index 6d65856..5a5c19d 100644
--- a/com/aelitis/azureus/core/security/impl/CryptoManagerImpl.java
+++ b/com/aelitis/azureus/core/security/impl/CryptoManagerImpl.java
@@ -25,7 +25,6 @@ package com.aelitis.azureus.core.security.impl;
 import java.util.*;
 
 import java.nio.ByteBuffer;
-import java.security.SecureRandom;
 
 import javax.crypto.Cipher;
 import javax.crypto.SecretKey;
@@ -50,7 +49,6 @@ import com.aelitis.azureus.core.security.CryptoManagerException;
 import com.aelitis.azureus.core.security.CryptoManagerKeyListener;
 import com.aelitis.azureus.core.security.CryptoManagerPasswordException;
 import com.aelitis.azureus.core.security.CryptoManagerPasswordHandler;
-import com.aelitis.azureus.core.security.CryptoManagerPasswordHandler.passwordDetails;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 
 public class 
@@ -59,7 +57,7 @@ CryptoManagerImpl
 {
 	private static final int 	PBE_ITERATIONS	= 100;
 	private static final String	PBE_ALG			= "PBEWithMD5AndDES";
-	
+		
 	private static CryptoManagerImpl		singleton;
 	
 	
@@ -290,6 +288,44 @@ CryptoManagerImpl
    	}
 	
 	protected passwordDetails
+	setPassword(
+		int				handler,
+		int				pw_type,
+		char[]			pw_chars,
+		long			timeout )
+	
+		throws CryptoManagerException
+	{
+		try{
+			String persist_timeout_key 	= CryptoManager.CRYPTO_CONFIG_PREFIX + "pw." + handler + ".persist_timeout";
+			String persist_pw_key 		= CryptoManager.CRYPTO_CONFIG_PREFIX + "pw." + handler + ".persist_value";
+			String persist_pw_key_type	= CryptoManager.CRYPTO_CONFIG_PREFIX + "pw." + handler + ".persist_type";
+	
+			byte[]	salt		= getPasswordSalt();
+			byte[]	pw_bytes	= new String( pw_chars ).getBytes( "UTF8" );
+			
+			SHA1 sha1 = new SHA1();
+			
+			sha1.update( ByteBuffer.wrap( salt ));
+			sha1.update( ByteBuffer.wrap( pw_bytes ));
+			
+			String	encoded_pw = ByteFormatter.encodeString( sha1.digest());
+
+			COConfigurationManager.setParameter( persist_timeout_key, timeout );
+			COConfigurationManager.setParameter( persist_pw_key_type, pw_type );
+			COConfigurationManager.setParameter( persist_pw_key, encoded_pw );
+
+			passwordDetails	result = new passwordDetails( encoded_pw.toCharArray(), pw_type );
+
+			return( result );
+			
+		}catch( Throwable e ){
+		
+			throw( new CryptoManagerException( "setPassword failed", e ));
+		}
+	}
+	
+	protected passwordDetails
 	getPassword(
 		int				handler,
 		int				action,
diff --git a/com/aelitis/azureus/core/subs/Subscription.java b/com/aelitis/azureus/core/subs/Subscription.java
index 686d67b..59e7c87 100644
--- a/com/aelitis/azureus/core/subs/Subscription.java
+++ b/com/aelitis/azureus/core/subs/Subscription.java
@@ -21,11 +21,14 @@
 
 package com.aelitis.azureus.core.subs;
 
+import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
+
 import com.aelitis.azureus.core.metasearch.Engine;
 import com.aelitis.azureus.core.vuzefile.VuzeFile;
 
 public interface 
 Subscription 
+	extends UtilitiesImpl.PluginSubscription
 {
 	public static final int AZ_VERSION	= 1;
 	
@@ -170,6 +173,15 @@ Subscription
 	public SubscriptionHistory
 	getHistory();
 	
+		/**
+		 * shortcut to help plugin interface
+		 * @param l
+		 */
+	
+	public SubscriptionResult[]
+	getResults(
+		boolean		include_deleted );
+	
 	public void
 	addListener(
 		SubscriptionListener		l );
diff --git a/com/aelitis/azureus/core/subs/SubscriptionManager.java b/com/aelitis/azureus/core/subs/SubscriptionManager.java
index 29d5f53..88ebe49 100644
--- a/com/aelitis/azureus/core/subs/SubscriptionManager.java
+++ b/com/aelitis/azureus/core/subs/SubscriptionManager.java
@@ -24,9 +24,11 @@ package com.aelitis.azureus.core.subs;
 import java.net.URL;
 import java.util.Map;
 
+import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
 
 public interface 
-SubscriptionManager 
+SubscriptionManager
+	extends UtilitiesImpl.PluginSubscriptionManager
 {
 	public Subscription
 	create(
@@ -127,6 +129,16 @@ SubscriptionManager
 	setAutoStartMaxMB(
 		int			mb );
 
+	public boolean
+	isRSSPublishEnabled();
+	
+	public void
+	setRSSPublishEnabled(
+		boolean		enabled );
+	
+	public String
+	getRSSLink();
+	
 	public void
 	addListener(
 		SubscriptionManagerListener	listener );
diff --git a/com/aelitis/azureus/core/subs/SubscriptionResult.java b/com/aelitis/azureus/core/subs/SubscriptionResult.java
index a9f97c0..3ae0bf1 100644
--- a/com/aelitis/azureus/core/subs/SubscriptionResult.java
+++ b/com/aelitis/azureus/core/subs/SubscriptionResult.java
@@ -23,8 +23,11 @@ package com.aelitis.azureus.core.subs;
 
 import java.util.Map;
 
+import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
+
 public interface 
 SubscriptionResult 
+	extends UtilitiesImpl.PluginSubscriptionResult
 {
 	public String
 	getID();
@@ -32,6 +35,14 @@ SubscriptionResult
 	public Map
 	toJSONMap();
 	
+		/**
+		 * See SearchResult properties for list
+		 * @return
+		 */
+	
+	public Map<Integer,Object>
+	toPropertyMap();
+	
 	public String
 	getDownloadLink();
 	
diff --git a/com/aelitis/azureus/core/subs/impl/SubscriptionHistoryImpl.java b/com/aelitis/azureus/core/subs/impl/SubscriptionHistoryImpl.java
index b00bee4..031ea27 100644
--- a/com/aelitis/azureus/core/subs/impl/SubscriptionHistoryImpl.java
+++ b/com/aelitis/azureus/core/subs/impl/SubscriptionHistoryImpl.java
@@ -842,6 +842,14 @@ SubscriptionHistoryImpl
 	}
 	
 	protected void
+	setFatalError(
+		String		_error )
+	{
+		last_error		= _error;
+		consec_fails	= 1024;
+	}
+	
+	protected void
 	setLastError(
 		String		_last_error,
 		boolean		_auth_failed )
diff --git a/com/aelitis/azureus/core/subs/impl/SubscriptionImpl.java b/com/aelitis/azureus/core/subs/impl/SubscriptionImpl.java
index b6da246..5d1d3df 100644
--- a/com/aelitis/azureus/core/subs/impl/SubscriptionImpl.java
+++ b/com/aelitis/azureus/core/subs/impl/SubscriptionImpl.java
@@ -58,6 +58,7 @@ import com.aelitis.azureus.core.subs.SubscriptionHistory;
 import com.aelitis.azureus.core.subs.SubscriptionListener;
 import com.aelitis.azureus.core.subs.SubscriptionManager;
 import com.aelitis.azureus.core.subs.SubscriptionPopularityListener;
+import com.aelitis.azureus.core.subs.SubscriptionResult;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.core.vuzefile.VuzeFile;
 import com.aelitis.azureus.core.vuzefile.VuzeFileHandler;
@@ -773,9 +774,22 @@ SubscriptionImpl
 	
 		throws SubscriptionException
 	{
-		SubscriptionBodyImpl body = new SubscriptionBodyImpl( manager, this );
+		try{
+			SubscriptionBodyImpl body = new SubscriptionBodyImpl( manager, this );
 
-		return( body.getJSON());
+			return( body.getJSON());
+			
+		}catch( Throwable e ){
+			
+			history.setFatalError( Debug.getNestedExceptionMessage(e));
+			
+			if ( e instanceof SubscriptionException ){
+				
+				throw((SubscriptionException)e );
+			}
+			
+			throw( new SubscriptionException( "Failed to read subscription", e ));
+		}
 	}
 	
 	public boolean
@@ -1832,6 +1846,13 @@ SubscriptionImpl
 		}
 	}
 	
+	public SubscriptionResult[]
+  	getResults(
+  		boolean		include_deleted )
+	{
+		return( getHistory().getResults( include_deleted ));
+	}
+	
 	public void
 	setUserData(
 		Object		key,
diff --git a/com/aelitis/azureus/core/subs/impl/SubscriptionManagerImpl.java b/com/aelitis/azureus/core/subs/impl/SubscriptionManagerImpl.java
index eb4ee09..f8056ab 100644
--- a/com/aelitis/azureus/core/subs/impl/SubscriptionManagerImpl.java
+++ b/com/aelitis/azureus/core/subs/impl/SubscriptionManagerImpl.java
@@ -89,13 +89,27 @@ SubscriptionManagerImpl
 	private static final String CONFIG_AUTO_START_MIN_MB 	= "subscriptions.auto.start.min.mb";
 	private static final String CONFIG_AUTO_START_MAX_MB 	= "subscriptions.auto.start.max.mb";
 	
-	
+	private static final String	RSS_ENABLE_CONFIG_KEY		= "subscriptions.config.rss_enable";
+
 	
 	private static SubscriptionManagerImpl		singleton;
+	private static boolean						pre_initialised;
+	
+	private static final int random_seed = RandomUtils.nextInt( 256 );
 	
 	public static void
 	preInitialise()
 	{
+		synchronized( SubscriptionManagerImpl.class ){
+			
+			if ( pre_initialised ){
+				
+				return;
+			}
+			
+			pre_initialised = true;
+		}
+		
 		VuzeFileHandler.getSingleton().addProcessor(
 			new VuzeFileProcessor()
 			{
@@ -143,7 +157,9 @@ SubscriptionManagerImpl
 	getSingleton(
 		boolean		stand_alone )
 	{
-		synchronized( SubscriptionManagerFactory.class ){
+		preInitialise();
+		
+		synchronized( SubscriptionManagerImpl.class ){
 			
 			if ( singleton != null ){
 			
@@ -217,6 +233,8 @@ SubscriptionManagerImpl
 	
 	private Pattern					exclusion_pattern = Pattern.compile( "azdev[0-9]+\\.azureus\\.com" );
 	
+	private SubscriptionRSSFeed		rss_publisher;
+	
 	private AEDiagnosticsLogger		logger;
 	
 	
@@ -310,13 +328,14 @@ SubscriptionManagerImpl
 	{
 		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(AzureusCore core) {
-				startUp(core);
+				initWithCore(core);
 			}
 		});
 	}
 
 	protected void
-	startUp(AzureusCore core)
+	initWithCore(
+		AzureusCore 	core )
 	{
 		synchronized( this ){
 			
@@ -330,6 +349,8 @@ SubscriptionManagerImpl
 
 		final PluginInterface default_pi = PluginInitializer.getDefaultInterface();
 
+		rss_publisher = new SubscriptionRSSFeed( this, default_pi );
+		
 		TorrentManager  tm = default_pi.getTorrentManager();
 		
 		ta_subs_download 		= tm.getPluginAttribute( "azsubs.subs_dl" );
@@ -613,6 +634,25 @@ SubscriptionManagerImpl
 		return( scheduler );
 	}
 	
+	public boolean
+	isRSSPublishEnabled()
+	{
+		return( COConfigurationManager.getBooleanParameter( RSS_ENABLE_CONFIG_KEY, false ));
+	}
+	
+	public void
+	setRSSPublishEnabled(
+		boolean		enabled )
+	{
+		COConfigurationManager.setParameter( RSS_ENABLE_CONFIG_KEY, enabled );
+	}
+	
+	public String
+	getRSSLink()
+	{
+		return( rss_publisher.getFeedURL());
+	}
+	
 	public Subscription 
 	create(
 		String			name,
@@ -4047,6 +4087,11 @@ SubscriptionManagerImpl
 	{
 		Map		details = subs.getPublicationDetails();					
 		
+			// inject a random element so we can count occurrences properly (as the DHT logic
+			// removes duplicates)
+		
+		details.put( "!", new Long( random_seed ));
+		
 		byte[] encoded = BEncoder.encode( details );
 		
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -4104,7 +4149,13 @@ SubscriptionManagerImpl
 			is.close();
 		}
 		
-		return( BDecoder.decode( to_decode ));
+		Map res = BDecoder.decode( to_decode );
+		
+			// remove any injected random seed
+		
+		res.remove( "!" );
+		
+		return( res );
 	}
 	
 	protected void
diff --git a/com/aelitis/azureus/core/subs/impl/SubscriptionRSSFeed.java b/com/aelitis/azureus/core/subs/impl/SubscriptionRSSFeed.java
new file mode 100644
index 0000000..2553fb4
--- /dev/null
+++ b/com/aelitis/azureus/core/subs/impl/SubscriptionRSSFeed.java
@@ -0,0 +1,328 @@
+/*
+ * Created on Jul 13, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.core.subs.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.util.Date;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.TimeFormatter;
+import org.gudy.azureus2.core3.util.UrlUtils;
+import org.gudy.azureus2.core3.xml.util.XUXmlWriter;
+
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageRequest;
+import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageResponse;
+import org.gudy.azureus2.plugins.utils.search.SearchResult;
+import org.gudy.azureus2.plugins.utils.subscriptions.Subscription;
+import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionManager;
+import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionResult;
+
+import com.aelitis.azureus.core.rssgen.RSSGeneratorPlugin;
+
+public class 
+SubscriptionRSSFeed 
+	implements RSSGeneratorPlugin.Provider
+{
+	private static final String PROVIDER = "subscriptions";
+	
+	private SubscriptionManagerImpl		manager;
+	private PluginInterface				plugin_interface;
+	
+	private RSSGeneratorPlugin		generator;
+	
+	protected
+	SubscriptionRSSFeed(
+		SubscriptionManagerImpl	_manager,
+		PluginInterface			_plugin_interface )
+	{
+		manager 			= _manager;
+		plugin_interface	= _plugin_interface;
+				
+		generator	= RSSGeneratorPlugin.getSingleton();
+		
+		generator.registerProvider( PROVIDER, this );
+	}
+		
+	public boolean
+	isEnabled()
+	{
+		return( manager.isRSSPublishEnabled());
+	}
+	
+	public String
+	getFeedURL()
+	{
+		return( generator.getURL() + PROVIDER );
+	}
+	
+	public boolean
+	generate(
+		TrackerWebPageRequest		request,
+		TrackerWebPageResponse		response )
+	
+		throws IOException
+	{
+		InetSocketAddress	local_address = request.getLocalAddress();
+		
+		if ( local_address == null ){
+			
+			return( false );
+		}
+		
+		URL	url	= request.getAbsoluteURL();
+					
+		String path = url.getPath();
+		
+		path = path.substring( PROVIDER.length()+1);
+		
+		try{
+			SubscriptionManager sman = plugin_interface.getUtilities().getSubscriptionManager();
+	
+			Subscription[] 	subs = sman.getSubscriptions();
+			
+			OutputStream os = response.getOutputStream();
+	
+			PrintWriter pw = new PrintWriter(new OutputStreamWriter( os, "UTF-8" ));
+	
+			if ( path.length() <= 1 ){
+				
+				response.setContentType( "text/html; charset=UTF-8" );
+				
+				pw.println( "<HTML><HEAD><TITLE>Vuze Subscription Feeds</TITLE></HEAD><BODY>" );
+				
+				for ( Subscription s: subs ){
+	
+					String	name = s.getName();
+									
+					pw.println( "<LI><A href=\"" + PROVIDER + "/" + s.getID() + "\">" + name + "</A></LI>" );
+				}
+				
+				pw.println( "</BODY></HTML>" );
+				
+			}else{
+				
+				String	id = path.substring( 1 );
+				
+				Subscription	subscription = null;
+				
+				for ( Subscription s: subs ){
+					
+					if ( s.getID().equals( id )){
+						
+						subscription = s;
+						
+						break;
+					}
+				}
+				
+				if ( subscription == null ){
+					
+					response.setReplyStatus( 404 );
+					
+					return( true );
+				}
+				
+				URL	feed_url = url;
+	
+					// absolute url is borked as it doesn't set the host properly. hack 
+				
+				String	host = (String)request.getHeaders().get( "host" );
+				
+				if ( host != null ){
+					
+					int	pos = host.indexOf( ':' );
+					
+					if ( pos != -1 ){
+						
+						host = host.substring( 0, pos );
+					}
+					
+					feed_url = UrlUtils.setHost( url, host );
+				}
+				
+				response.setContentType( "application/xml" );
+				
+				pw.println( "<?xml version=\"1.0\" encoding=\"utf-8\"?>" );
+				
+				pw.println( 
+						"<rss version=\"2.0\" " + 
+						"xmlns:vuze=\"http://www.vuze.com\" " +
+						"xmlns:media=\"http://search.yahoo.com/mrss/\" " +
+						"xmlns:atom=\"http://www.w3.org/2005/Atom\" " +
+						"xmlns:itunes=\"http://www.itunes.com/dtds/podcast-1.0.dtd\">" );
+				
+				pw.println( "<channel>" );
+				
+				String channel_title = "Vuze Subscription: " + escape( subscription.getName());
+						
+				pw.println( "<title>" + channel_title + "</title>" );
+				pw.println( "<link>http://vuze.com</link>" );
+				pw.println( "<atom:link href=\"" + escape( feed_url.toExternalForm()) + "\" rel=\"self\" type=\"application/rss+xml\" />" );
+				
+				pw.println( "<description>Vuze RSS Feed for subscription " + escape( subscription.getName()) + "</description>" );
+				
+				pw.println("<itunes:image href=\"http://www.vuze.com/img/vuze_icon_128.png\"/>");
+				pw.println("<image><url>http://www.vuze.com/img/vuze_icon_128.png</url><title>" + channel_title + "</title><link>http://vuze.com</link></image>");
+				
+						
+				SubscriptionResult[] results = subscription.getResults();
+
+											
+				String	feed_date_key = "subscriptions.feed_date." + subscription.getID();
+				
+				long feed_date = COConfigurationManager.getLongParameter( feed_date_key );
+	
+				boolean new_date = false;
+				
+				for ( SubscriptionResult result: results ){
+				
+					Date date = (Date)result.getProperty( SearchResult.PR_PUB_DATE );
+					
+					long 	millis = date.getTime();
+					
+					if ( millis > feed_date ){
+						
+						feed_date = millis;
+						
+						new_date = true;
+					}
+				}
+				
+				if ( new_date ){
+					
+					COConfigurationManager.setParameter( feed_date_key, feed_date );
+				}
+				
+				pw.println(	"<pubDate>" + TimeFormatter.getHTTPDate( feed_date ) + "</pubDate>" );
+	
+				
+				for ( SubscriptionResult result: results ){
+											
+					try{
+		  				pw.println( "<item>" );
+		  				
+		  				String	name = (String)result.getProperty( SearchResult.PR_NAME );
+		  				
+		  				pw.println( "<title>" + escape( name ) + "</title>" );
+		  					
+						Date date = (Date)result.getProperty( SearchResult.PR_PUB_DATE );
+						
+						if ( date != null ){
+		  
+							pw.println(	"<pubDate>" + TimeFormatter.getHTTPDate( date.getTime()) + "</pubDate>" );
+						}
+						
+						String	uid = (String)result.getProperty( SearchResult.PR_UID );
+						
+						if ( uid != null ){
+		  				
+							pw.println( "<guid isPermaLink=\"false\">" + escape(uid ) + "</guid>" );
+						}
+						
+						String	link = (String)result.getProperty( SearchResult.PR_DOWNLOAD_LINK );
+						Long	size = (Long)result.getProperty( SearchResult.PR_SIZE );
+
+						if ( link != null ){
+							
+							pw.println( "<link>" + link + "</link>" );
+						
+
+							if ( size != null ){
+							
+								pw.println( "<media:content fileSize=\"" + size + "\" url=\"" + link + "\"/>" );
+							}
+						}
+						
+						if ( size != null ){
+
+							pw.println( "<vuze:size>" + size + "</vuze:size>" );
+						}
+						
+						Long	seeds = (Long)result.getProperty( SearchResult.PR_SEED_COUNT );
+						
+						if ( seeds != null ){
+							
+							pw.println( "<vuze:seeds>" + seeds + "</vuze:seeds>" );
+						}
+						
+						Long	peers = (Long)result.getProperty( SearchResult.PR_LEECHER_COUNT );
+						
+						if ( peers != null ){
+							
+							pw.println( "<vuze:peers>" + peers + "</vuze:peers>" );
+						}
+
+						Long	rank = (Long)result.getProperty( SearchResult.PR_RANK );
+						
+						if ( rank != null ){
+							
+							pw.println( "<vuze:rank>" + rank + "</vuze:rank>" );
+						}
+
+						
+		  				pw.println( "</item>" );
+		  				
+					}catch( Throwable e ){
+						
+						Debug.out(e);
+					}
+				}
+			
+				pw.println( "</channel>" );
+				
+				pw.println( "</rss>" );
+			}
+			
+			pw.flush();
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+			
+			throw( new IOException( Debug.getNestedExceptionMessage( e )));
+		}
+		
+		return( true );
+	}
+	
+	protected String
+	escape(
+		String	str )
+	{
+		return( XUXmlWriter.escapeXML(str));
+	}
+
+	protected String
+	escapeMultiline(
+		String	str )
+	{
+		return( XUXmlWriter.escapeXML(str.replaceAll("[\r\n]+", "<BR>")));
+	}
+}
diff --git a/com/aelitis/azureus/core/subs/impl/SubscriptionResultImpl.java b/com/aelitis/azureus/core/subs/impl/SubscriptionResultImpl.java
index 13e7bc3..374d3eb 100644
--- a/com/aelitis/azureus/core/subs/impl/SubscriptionResultImpl.java
+++ b/com/aelitis/azureus/core/subs/impl/SubscriptionResultImpl.java
@@ -27,6 +27,7 @@ import org.gudy.azureus2.core3.util.Base32;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.DisplayFormatters;
 import org.gudy.azureus2.core3.util.SHA1Simple;
+import org.gudy.azureus2.plugins.utils.search.SearchResult;
 
 import com.aelitis.azureus.core.metasearch.Result;
 import com.aelitis.azureus.core.subs.SubscriptionResult;
@@ -73,7 +74,7 @@ SubscriptionResultImpl
 		
 		String	uid = result.getUID();
 		
-		if ( uid != null ){
+		if ( uid != null && uid.length() > 0 ){
 		
 			String	key2_str = result.getEngine().getId() + ":" + uid;
 			
@@ -296,4 +297,60 @@ SubscriptionResultImpl
 	{
 		return((String)toJSONMap().get( "h" ));
 	}
+	
+	public Map<Integer,Object>
+	toPropertyMap()
+	{
+		Map map = toJSONMap();
+		
+		Map<Integer,Object>	result = new HashMap<Integer, Object>();
+		
+		String title = (String)map.get( "n" );
+		
+		result.put( SearchResult.PR_UID, getID());
+		result.put( SearchResult.PR_NAME, title );
+		
+		String pub_date = (String)map.get( "ts" );
+		if ( pub_date != null ){	
+			result.put( SearchResult.PR_PUB_DATE, new Date( Long.parseLong( pub_date )));
+		}
+		
+		String size = (String)map.get( "lb" );
+		if ( size != null ){	
+			result.put( SearchResult.PR_SIZE, Long.parseLong( size ));
+		}
+		
+		String	link = (String)map.get( "dbl" );
+		
+		if ( link == null ){
+			
+			link = (String)map.get( "dl" );
+		}		
+		
+		if ( link != null ){
+			result.put( SearchResult.PR_DOWNLOAD_LINK, link );
+		}
+		
+		String	hash = (String)map.get( "h" );
+		if ( hash != null ){
+			result.put( SearchResult.PR_HASH, hash );
+		}
+		
+		String	seeds = (String)map.get( "s" );
+		if ( seeds != null ){
+			result.put( SearchResult.PR_SEED_COUNT, Long.parseLong(seeds) );
+		}
+		
+		String	peers = (String)map.get( "p" );
+		if ( peers != null ){
+			result.put( SearchResult.PR_LEECHER_COUNT, Long.parseLong(peers) );
+		}
+		
+		String	rank = (String)map.get( "r" );
+		if ( rank != null ){
+			result.put( SearchResult.PR_RANK, (long)(100*Float.parseFloat( rank )));
+		}
+		
+		return( result );
+	}
 }
diff --git a/com/aelitis/azureus/core/torrent/GlobalRatingUtils.java b/com/aelitis/azureus/core/torrent/GlobalRatingUtils.java
deleted file mode 100644
index 0c7bf5d..0000000
--- a/com/aelitis/azureus/core/torrent/GlobalRatingUtils.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package com.aelitis.azureus.core.torrent;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.torrent.TOTorrentException;
-import org.gudy.azureus2.core3.util.*;
-
-import com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger;
-
-/**
- * @author TuxPaper
- * @created Oct 24, 2006
- *
- */
-public class GlobalRatingUtils
-{
-	private static final String TOR_AZ_PROP_GLOBAL_RATING = "GlobalRating";
-
-	private static final String GLOBAL_RATING_STRING = "String";
-
-	private static final String GLOBAL_RATING_COLOR = "Color";
-
-	private static final String GLOBAL_RATING_COUNT = "Count";
-
-	private static final String GLOBAL_RATING_REFRESH_ON = "Refresh On";
-
-	public static final int RATING_WAITING = -2;
-
-	public static final int RATING_NONE = -1;
-
-	public static final int RATING_THUMBDOWN = 0;
-
-	public static final int RATING_THUMBUP = 1;
-
-	private static Map getTempGlobalRatingContentMap(TOTorrent torrent) {
-		Map mapContent = PlatformTorrentUtils.getTempContentMap(torrent);
-		Object o = mapContent.get(TOR_AZ_PROP_GLOBAL_RATING);
-
-		if (o instanceof Map) {
-			return (Map) o;
-		}
-
-		Map map = new HashMap();
-		mapContent.put(TOR_AZ_PROP_GLOBAL_RATING, map);
-		return map;
-	}
-
-	/**
-	 * @param torrent
-	 * @return
-	 */
-	public static String getRatingString(TOTorrent torrent) {
-		Map mapContent = getTempGlobalRatingContentMap(torrent);
-		Object o = mapContent.get(GLOBAL_RATING_STRING);
-		if (o instanceof String) {
-			return (String) o;
-		} else if (o instanceof byte[]) {
-			return new String((byte[]) o);
-		}
-
-		if (o != null) {
-			Debug.out(GLOBAL_RATING_STRING + " is not String - " + o.getClass() + "("
-					+ o + ")");
-		}
-		return null;
-	}
-
-	public static void setRating(final TOTorrent torrent, String rating,
-			String color, long count, long refreshOn) {
-		if (torrent == null) {
-			return;
-		}
-
-		Map mapContent = getTempGlobalRatingContentMap(torrent);
-		if (rating == null) {
-			mapContent.remove(GLOBAL_RATING_STRING);
-		} else {
-			mapContent.put(GLOBAL_RATING_STRING, rating);
-		}
-		if (color == null) {
-			mapContent.remove(GLOBAL_RATING_COLOR);
-		} else {
-			mapContent.put(GLOBAL_RATING_COLOR, color);
-		}
-
-		mapContent.put(GLOBAL_RATING_REFRESH_ON, new Long(refreshOn));
-		mapContent.put(GLOBAL_RATING_COUNT, new Long(count));
-
-		try {
-			TorrentUtils.writeToFile(torrent);
-		} catch (TOTorrentException e) {
-			Debug.out(e);
-		}
-
-		if (PlatformTorrentUtils.DEBUG_CACHING) {
-			try {
-				PlatformTorrentUtils.log("v3.GR.caching: setRating to " + rating
-						+ " for " + torrent.getHashWrapper().toBase32String() + ".  Next refresh in "
-						+ (refreshOn - SystemTime.getCurrentTime()));
-			} catch (TOTorrentException e) {
-			}
-		}
-		SimpleTimer.addEvent("Update G.Rating", refreshOn,
-				new TimerEventPerformer() {
-					public void perform(TimerEvent event) {
-						if (PlatformTorrentUtils.DEBUG_CACHING) {
-							PlatformTorrentUtils.log("v3.GR.caching: refresh timer calling updateFromPlatform");
-						}
-						PlatformRatingMessenger.updateGlobalRating(torrent, 15000);
-					}
-				});
-	}
-
-	public static String getColor(TOTorrent torrent) {
-		Map mapContent = getTempGlobalRatingContentMap(torrent);
-		Object o = mapContent.get(GLOBAL_RATING_COLOR);
-		if (o instanceof String) {
-			return (String) o;
-		} else if (o instanceof byte[]) {
-			return new String((byte[]) o);
-		}
-		if (o != null) {
-			Debug.out(GLOBAL_RATING_COLOR + " is not String - " + o.getClass() + "("
-					+ o + ")");
-		}
-		return null;
-	}
-
-	public static long getRefreshOn(TOTorrent torrent) {
-		Map mapContent = getTempGlobalRatingContentMap(torrent);
-		Long l = (Long) mapContent.get(GLOBAL_RATING_REFRESH_ON);
-		if (l == null) {
-			return SystemTime.getCurrentTime();
-		}
-		return l.longValue();
-	}
-
-	public static long getCount(TOTorrent torrent) {
-		Map mapContent = getTempGlobalRatingContentMap(torrent);
-		Long l = (Long) mapContent.get(GLOBAL_RATING_COUNT);
-		if (l == null) {
-			return 0;
-		}
-		return l.longValue();
-	}
-}
diff --git a/com/aelitis/azureus/core/torrent/MetaDataUpdateListener.java b/com/aelitis/azureus/core/torrent/MetaDataUpdateListener.java
deleted file mode 100644
index 5213a96..0000000
--- a/com/aelitis/azureus/core/torrent/MetaDataUpdateListener.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package com.aelitis.azureus.core.torrent;
-
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-
-/**
- * @author TuxPaper
- * @created Nov 3, 2006
- *
- */
-public interface MetaDataUpdateListener
-{
-	public void metaDataUpdated(TOTorrent torrent);
-}
diff --git a/com/aelitis/azureus/core/torrent/PlatformRatingInfoList.java b/com/aelitis/azureus/core/torrent/PlatformRatingInfoList.java
deleted file mode 100644
index 66e58d9..0000000
--- a/com/aelitis/azureus/core/torrent/PlatformRatingInfoList.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- * Created on Mar 27, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
- 
-package com.aelitis.azureus.core.torrent;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.gudy.azureus2.core3.util.Debug;
-
-import com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author TuxPaper
- * @created Mar 27, 2008
- *
- */
-public class PlatformRatingInfoList
-	extends RatingInfoList
-{
-	/**
-	 * Map: 
-	 * Key = Torrent Hash
-	 * Value = Map
-	 * 
-	 *   Map 2:
-	 *   Key = Rating Type
-	 *   Value = Map
-	 *   
-	 *     Map 3:
-	 *     Keys = average, count, expires-in-mins
-	 * @param reply
-	 */
-	private final Map reply;
-
-	/**
-	 * 
-	 */
-	public PlatformRatingInfoList(Map message) {
-		reply = message == null ? new HashMap() : message;
-	}
-
-	public boolean hasHash(String hash) {
-		return reply.get(hash) != null;
-	}
-
-	public long getRatingValue(String hash, String type) {
-		int rating = -1;
-
-		Map mapRating = (Map) reply.get(hash);
-		if (mapRating != null) {
-			Map mapValues = (Map) mapRating.get(PlatformRatingMessenger.RATE_TYPE_CONTENT);
-			if (mapValues != null) {
-				Object val = mapValues.get("value");
-				if (val instanceof Number) {
-					rating = ((Number) val).intValue();
-				}
-			}
-		}
-
-		return rating;
-	}
-
-	public long getRatingCount(String hash, String type) {
-		long rating = -1;
-		try {
-			Map mapRating = (Map) reply.get(hash);
-			if (mapRating != null) {
-				Map mapValues = (Map) mapRating.get(PlatformRatingMessenger.RATE_TYPE_CONTENT);
-				if (mapValues != null) {
-					Object val = mapValues.get("count");
-					if (val instanceof Number) {
-						rating = ((Number) val).longValue();
-					}
-				}
-			}
-		} catch (Exception e) {
-			Debug.out(e);
-		}
-
-		return rating;
-	}
-
-	public String getRatingString(String hash, String type) {
-		String rating = "--";
-
-		try {
-			Map mapRating = (Map) reply.get(hash);
-			if (mapRating != null) {
-				Map mapValues = (Map) mapRating.get(PlatformRatingMessenger.RATE_TYPE_CONTENT);
-				if (mapValues != null) {
-					Object val = mapValues.get("value");
-					if (val instanceof String) {
-						rating = (String) val;
-					} else if (val instanceof Double) {
-						rating = ((Double) val).toString();
-					}
-				}
-			}
-		} catch (Exception e) {
-			Debug.out(e);
-		}
-
-		return rating;
-	}
-
-	public String getRatingColor(String hash, String type) {
-		String color = null;
-
-		try {
-			Map mapRating = (Map) reply.get(hash);
-			if (mapRating != null) {
-				Map mapValues = (Map) mapRating.get(PlatformRatingMessenger.RATE_TYPE_CONTENT);
-				if (mapValues != null) {
-					Map map = (Map) MapUtils.getMapObject(mapRating,
-							"display-settings", null, Map.class);
-					if (map != null && map.containsKey("color")) {
-						color = (String) map.get("color");
-					}
-				}
-			}
-		} catch (Exception e) {
-			Debug.out(e);
-		}
-
-		return color;
-	}
-
-	public long getRatingExpireyMins(String hash, String type) {
-		long expiryMins = -1;
-		try {
-			Map mapRating = (Map) reply.get(hash);
-			if (mapRating != null) {
-				Map mapValues = (Map) mapRating.get(PlatformRatingMessenger.RATE_TYPE_CONTENT);
-				if (mapValues != null) {
-					Object val = mapValues.get("expires-in-mins");
-					if (val instanceof Long) {
-						expiryMins = ((Long) val).longValue();
-					}
-				}
-			}
-		} catch (Exception e) {
-			Debug.out(e);
-		}
-
-		return expiryMins;
-	}
-
-	/**
-	 * @return
-	 */
-	public Map getMap() {
-		return reply;
-	}
-}
diff --git a/com/aelitis/azureus/core/torrent/PlatformTorrentUtils.java b/com/aelitis/azureus/core/torrent/PlatformTorrentUtils.java
index b131d9c..915a0b6 100644
--- a/com/aelitis/azureus/core/torrent/PlatformTorrentUtils.java
+++ b/com/aelitis/azureus/core/torrent/PlatformTorrentUtils.java
@@ -25,24 +25,19 @@ import java.net.InetAddress;
 import java.net.URL;
 import java.util.*;
 
-import org.bouncycastle.util.encoders.Base64;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.global.GlobalManager;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLSet;
 import org.gudy.azureus2.core3.torrent.TOTorrentException;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentImpl;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.messenger.PlatformMessenger;
-import com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger;
-import com.aelitis.azureus.core.messenger.config.PlatformTorrentMessenger;
-
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.torrent.Torrent;
 
 /**
  * @author TuxPaper
@@ -51,15 +46,10 @@ import org.gudy.azureus2.plugins.torrent.Torrent;
  */
 public class PlatformTorrentUtils
 {
-	private static final long RETRY_METADATA = 10 * 60 * 1000;
-
 	private static final long MIN_SPEED_DEFAULT = 100 * 1024;
 
-	private static final long MIN_MD_REFRESH_MS = 1000 * 60;
-
-	private static final long MAX_MD_REFRESH_MS = 1000L * 60 * 60 * 24 * 30;
-
-	public static final String AELITIS_HOST_CORE	= "aelitis.com";			// needs to be lowercase
+	public static final String AELITIS_HOST_CORE	= ".aelitis.com";			// needs to be lowercase
+	public static final String VUZE_HOST_CORE		= ".vuze.com";				// needs to be lowercase
 
 	public static final boolean DEBUG_CACHING = System.getProperty(
 			"az3.debug.caching", "0").equals("1");
@@ -86,14 +76,6 @@ public class PlatformTorrentUtils
 
 	private static final String TOR_AZ_PROP_QUALITY = "Quality";
 
-	private static final String TOR_AZ_PROP_USER_RATING = "UserRating";
-
-	private static final String TOR_AZ_PROP_LASTUPDATED = "Revision Date";
-
-	private static final String TOR_AZ_PROP_CREATIONDATE = "Creation Date";
-
-	private static final String TOR_AZ_PROP_METADATA_REFRESHON = "Refresh On";
-
 	private static final String TOR_AZ_PROP_PROGRESSIVE = "Progressive";
 
 	private static final String TOR_AZ_PROP_SPEED = "Speed Bps";
@@ -108,33 +90,27 @@ public class PlatformTorrentUtils
 
 	private static final String TOR_AZ_PROP_CONTENT_NETWORK = "Content Network";
 		
-	private static final String TOR_AZ_PROP_AD_ID = "Ad ID";
-
-	private static final String TOR_AZ_PROP_AD_ENABLED = "Ad Enabled";
-
 	private static final String TOR_AZ_PROP_EXPIRESON = "Expires On";
 	
 	private static final String TOR_AZ_PROP_PRIMARY_FILE = "Primary File Index";
 
-	private static final ArrayList metaDataListeners = new ArrayList(1);
-
-	private static final ArrayList hasBeenOpenedListeners = new ArrayList(1);
+	private static final ArrayList<HasBeenOpenedListener> hasBeenOpenedListeners = new ArrayList<HasBeenOpenedListener>(1);
 
 	private static final String TOR_AZ_PROP_USE_EMP = "useEMP";
 	
 	private static final String TOR_AZ_PROP_FILE_METADATA = "File MetaData";
 	
-	private static final String TOR_AZ_PROP_WEB_AD_ENABLED = "Web Ad Enabled";
-
 	private static final String TOR_AZ_PROP_VIDEO_WIDTH = "Video Width";
 
 	private static final String TOR_AZ_PROP_VIDEO_HEIGHT = "Video Height";
 
 	private static final String TOR_AZ_PROP_VIDEO_RUNNINGTIME = "Running Time";
+	
+	private static final String TOR_AZ_PROP_DURATION_MILLIS = "Duration";
 
 	private static final String TOR_AZ_PROP_OPENED = "Opened";
 
-	private static ArrayList listPlatformHosts = null;
+	private static ArrayList<String> listPlatformHosts = null;
 
 	private static final Map mapPlatformTrackerTorrents = new WeakHashMap();
 
@@ -190,7 +166,7 @@ public class PlatformTorrentUtils
 		return mapContent;
 	}
 
-	private static String getContentMapString(TOTorrent torrent, String key) {
+	public static String getContentMapString(TOTorrent torrent, String key) {
 		if (torrent == null) {
 			return null;
 		}
@@ -296,6 +272,10 @@ public class PlatformTorrentUtils
 	public static String getContentDescription(TOTorrent torrent) {
 		return getContentMapString(torrent, TOR_AZ_PROP_DESCRIPTION);
 	}
+	
+	public static void setContentDescription(TOTorrent torrent, String desc) {
+		setContentMapString(torrent, TOR_AZ_PROP_DESCRIPTION,desc);
+	}
 
 	public static String getContentType(TOTorrent torrent) {
 		return getContentMapString(torrent, TOR_AZ_PROP_CONTENT_TYPE);
@@ -403,6 +383,10 @@ public class PlatformTorrentUtils
 		return getContentMapString(torrent, TOR_AZ_PROP_THUMBNAIL_URL);
 	}
 
+	public static void setContentThumbnailUrl(TOTorrent torrent, String url) {
+		setContentMapString(torrent, TOR_AZ_PROP_THUMBNAIL_URL, url);
+	}
+	
 	public static void setContentThumbnail(TOTorrent torrent, byte[] thumbnail) {
 		Map mapContent = getContentMap(torrent);
 		putOrRemove(mapContent, TOR_AZ_PROP_THUMBNAIL, thumbnail);
@@ -410,55 +394,6 @@ public class PlatformTorrentUtils
 		writeTorrentIfExists(torrent);
 	}
 
-	public static void setUserRating(TOTorrent torrent, int rating) {
-		if (torrent == null || getUserRating(torrent) == rating) {
-			return;
-		}
-		Map mapContent = getTempContentMap(torrent);
-		mapContent.put(TOR_AZ_PROP_USER_RATING, new Long(rating));
-		writeTorrentIfExists(torrent);
-		RatingInfoList ratingReply = new SingleUserRatingInfo(torrent);
-		PlatformRatingMessenger.invokeUpdateListeners(ratingReply);
-	}
-
-	public static void removeUserRating(TOTorrent torrent) {
-		Map mapContent = getTempContentMap(torrent);
-		if (mapContent.remove(TOR_AZ_PROP_USER_RATING) != null) {
-			writeTorrentIfExists(torrent);
-			RatingInfoList ratingReply = new SingleUserRatingInfo(torrent);
-			PlatformRatingMessenger.invokeUpdateListeners(ratingReply);
-		}
-	}
-
-	/**
-	 * 
-	 * @param torrent
-	 * @return -1: No rating
-	 */
-	public static int getUserRating(TOTorrent torrent) {
-		Map mapContent = getTempContentMap(torrent);
-		Long l = (Long) mapContent.get(TOR_AZ_PROP_USER_RATING);
-		if (l == null) {
-			return -1;
-		}
-		return l.intValue();
-	}
-
-	public static long getMetaDataRefreshOn(TOTorrent torrent) {
-		Map mapContent = getTempContentMap(torrent);
-		Long l = (Long) mapContent.get(TOR_AZ_PROP_METADATA_REFRESHON);
-		if (l == null) {
-			return 0;
-		}
-		return l.longValue();
-	}
-
-	public static void setMetaDataRefreshOn(TOTorrent torrent, long refreshOn) {
-		Map mapContent = getTempContentMap(torrent);
-		mapContent.put(TOR_AZ_PROP_METADATA_REFRESHON, new Long(refreshOn));
-		writeTorrentIfExists(torrent);
-	}
-
 	public static boolean isContent(TOTorrent torrent,
 			boolean requirePlatformTracker) {
 		if (torrent == null) {
@@ -481,9 +416,9 @@ public class PlatformTorrentUtils
 		return false;
 	}
 
-	public static List getPlatformHosts() {
+	public static List<String> getPlatformHosts() {
 		if (listPlatformHosts == null) {
-			listPlatformHosts = new ArrayList();
+			listPlatformHosts = new ArrayList<String>();
 			for (int i = 0; i < Constants.AZUREUS_DOMAINS.length; i++) {
 				listPlatformHosts.add(Constants.AZUREUS_DOMAINS[i].toLowerCase());
 			}
@@ -492,7 +427,7 @@ public class PlatformTorrentUtils
 	}
 
 	public static void addPlatformHost(String host) {
-		List platformHosts = getPlatformHosts();
+		List<String> platformHosts = getPlatformHosts();
 		host = host.toLowerCase();
 
 		if (!platformHosts.contains(host)) {
@@ -613,7 +548,9 @@ public class PlatformTorrentUtils
 			URL announceURL = torrent.getAnnounceURL();
 
 			if (announceURL != null) {
-				if (announceURL.getHost().indexOf(AELITIS_HOST_CORE) == -1) {
+				String	host = announceURL.getHost();
+				
+				if (!( host.endsWith(AELITIS_HOST_CORE)|| host.endsWith( VUZE_HOST_CORE ))){
 					isUpdate = false;
 				}
 			}
@@ -627,7 +564,9 @@ public class PlatformTorrentUtils
 
 					for (int j = 0; j < urls.length; j++) {
 
-						if (urls[j].getHost().indexOf(AELITIS_HOST_CORE) == -1) {
+						String host = urls[j].getHost();
+						
+						if (!( host.endsWith(AELITIS_HOST_CORE)|| host.endsWith( VUZE_HOST_CORE ))){
 							isUpdate = false;
 							break;
 						}
@@ -640,213 +579,6 @@ public class PlatformTorrentUtils
 		return isUpdate;
 	}
 
-	public static String getAdId(TOTorrent torrent) {
-		return getContentMapString(torrent, TOR_AZ_PROP_AD_ID);
-	}
-
-	public static void setAdId(TOTorrent torrent, String sID) {
-		Map mapContent = getContentMap(torrent);
-		putOrRemove(mapContent, TOR_AZ_PROP_AD_ID, sID);
-
-		writeTorrentIfExists(torrent);
-	}
-
-
-	/**
-	 * @param torrent
-	 * @param maxDelayMS TODO
-	 *
-	public static void updateMetaData(final TOTorrent[] torrents, long maxDelayMS) {
-		if (torrents == null) {
-			log("no torrents to update MD on");
-			return;
-		}
-
-		log("update " + torrents.length + " MD");
-
-		PlatformTorrentMessenger.getMetaData(torrents, maxDelayMS,
-				new PlatformTorrentMessenger.GetMetaDataReplyListener() {
-
-			public void messageSent() {
-			}
-
-			public void replyReceived(String replyType, Map mapHashes) {
-				for (Iterator iter = mapHashes.keySet().iterator(); iter.hasNext();) {
-					String hash = (String) iter.next();
-					updateMetaData_handleReply(null, hash, replyType, mapHashes);
-				}
-			}
-		});
-	}
-*/
-	/**
-	 * @param torrent
-	 * @param maxDelayMS TODO
-	 */
-	public static void updateMetaData(final TOTorrent torrent, long maxDelayMS) {
-		if (!isContent(torrent, true)) {
-			log(torrent, "torrent " + new String(torrent.getName())
-					+ " not az content");
-			return;
-		}
-
-		log(torrent, "updateMD");
-
-		PlatformTorrentMessenger.getMetaData(getContentNetworkID(torrent),
-				new TOTorrent[] {
-					torrent
-				}, maxDelayMS, new PlatformTorrentMessenger.GetMetaDataReplyListener() {
-
-					public void messageSent() {
-					}
-
-					public void replyReceived(String replyType, Map mapHashes) {
-						updateMetaData_handleReply(torrent, null, replyType, mapHashes);
-					}
-				});
-	}
-
-	private static void updateMetaData_handleReply(TOTorrent torrent,
-			String hash, String replyType, Map mapHashes) {
-		if (hash == null && torrent != null) {
-			try {
-				hash = torrent.getHashWrapper().toBase32String();
-			} catch (Exception e) {
-			}
-		}
-
-		GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
-		DownloadManager dm = gm.getDownloadManager(new HashWrapper(Base32.decode(hash)));
-
-		if (torrent == null && dm != null) {
-			torrent = dm.getTorrent();
-		}
-		Map contentMap = PlatformTorrentUtils.getContentMap(torrent);
-
-		final TOTorrent torrentFinal = torrent;
-		
-		if (replyType.equals(PlatformMessenger.REPLY_EXCEPTION)) {
-			if (torrent != null) {
-  			// try again in a bit
-  			log(torrent, "Exception, retrying later (~" + RETRY_METADATA + "ms)");
-  			SimpleTimer.addEvent("Update MD Retry", SystemTime.getCurrentTime()
-  					+ RETRY_METADATA, new TimerEventPerformer() {
-  				public void perform(TimerEvent event) {
-  					log(torrentFinal, "retry time");
-  					PlatformTorrentUtils.updateMetaData(torrentFinal, 15000);
-  				}
-  			});
-			}
-		} else {
-			Map jsonMapMetaData = hash == null ? null : (Map) mapHashes.get(hash);
-			if (jsonMapMetaData != null && !jsonMapMetaData.isEmpty()) {
-				long oldLastUpdated = getContentLastUpdated(torrent);
-				long expireyMins = 0;
-
-				for (Iterator iter = jsonMapMetaData.keySet().iterator(); iter.hasNext();) {
-					String key = (String) iter.next();
-					Object value = jsonMapMetaData.get(key);
-
-					if (value == null || value.equals(null)) {
-						contentMap.remove(key);
-					} else if ((key.equals("Thumbnail") || key.endsWith(".B64"))
-							&& value instanceof String) {
-						contentMap.put(key, Base64.decode((String) value));
-					} else if (key.equals("expires-in-mins") && value instanceof Long) {
-						expireyMins = ((Long) value).longValue();
-					} else {
-						contentMap.put(key, value);
-					}
-					writeTorrentIfExists(torrent);
-				}
-
-				// crappy way of updating the display name
-				if (dm != null) {
-					String title = PlatformTorrentUtils.getContentTitle(torrent);
-					if (title != null && title.length() > 0
-							&& dm.getDownloadState().getDisplayName() == null) {
-						dm.getDownloadState().setDisplayName(title);
-					}
-				}
-				triggerMetaDataUpdateListeners(torrent);
-
-				if (torrent != null) {
-					// setup next refresh
-
-  				long refreshOn;
-  				if (expireyMins > 0) {
-  					refreshOn = SystemTime.getCurrentTime() + (expireyMins * 60 * 1000L);
-  				} else {
-  					long newLastUpdated = getContentLastUpdated(torrent);
-  
-  					long diff = newLastUpdated - oldLastUpdated;
-  					log(torrent, "Last Updated: new " + new Date(newLastUpdated)
-  							+ ";old " + new Date(oldLastUpdated) + ";diff=" + diff);
-  					if (diff > 0 && oldLastUpdated != 0) {
-  						diff *= 2;
-  						if (diff < MIN_MD_REFRESH_MS) {
-  							diff = MIN_MD_REFRESH_MS;
-  						} else if (diff > MAX_MD_REFRESH_MS) {
-  							diff = MAX_MD_REFRESH_MS;
-  						}
-  						refreshOn = SystemTime.getOffsetTime(diff);
-  					} else {
-  						refreshOn = SystemTime.getCurrentTime()
-  								+ (7 * 24 * 60 * 60 * 1000L);
-  					}
-  				}
-  
-  				log(torrent, "got MD. Next refresh in "
-  						+ (refreshOn - SystemTime.getCurrentTime()));
-  				setMetaDataRefreshOn(torrent, refreshOn);
-  				SimpleTimer.addEvent("Update MD", refreshOn, new TimerEventPerformer() {
-  					public void perform(TimerEvent event) {
-  						PlatformTorrentUtils.updateMetaData(torrentFinal, 15000);
-  					}
-  				});
-				}
-			} else if (torrent != null) {
-				long refreshOn = SystemTime.getCurrentTime()
-						+ (30 * 24 * 60 * 60 * 1000L);
-				setMetaDataRefreshOn(torrent, refreshOn);
-				log(torrent, "no hash in reply. Next refresh on " + new Date(refreshOn));
-			}
-		}
-	}
-
-	public static void addListener(MetaDataUpdateListener l) {
-		if (metaDataListeners.indexOf(l) < 0) {
-			metaDataListeners.add(l);
-		}
-	}
-
-	public static void removeListener(MetaDataUpdateListener l) {
-		metaDataListeners.remove(l);
-	}
-
-	public static void triggerMetaDataUpdateListeners(TOTorrent torrent) {
-		if (torrent == null) {
-			return;
-		}
-		MetaDataUpdateListener[] listeners = (MetaDataUpdateListener[]) metaDataListeners.toArray(new MetaDataUpdateListener[0]);
-		for (int i = 0; i < listeners.length; i++) {
-			MetaDataUpdateListener listener = listeners[i];
-			try {
-				listener.metaDataUpdated(torrent);
-			} catch (Exception e) {
-				Debug.out(e);
-			}
-		}
-	}
-
-	public static long getContentLastUpdated(TOTorrent torrent) {
-		return getContentMapLong(torrent, TOR_AZ_PROP_LASTUPDATED, 0);
-	}
-
-	public static void setContentLastUpdated(TOTorrent torrent, long lastUpdate) {
-		setContentMapLong(torrent, TOR_AZ_PROP_LASTUPDATED, lastUpdate);
-	}
-
 	public static boolean isContentProgressive(TOTorrent torrent) {
 		return getContentMapLong(torrent, TOR_AZ_PROP_PROGRESSIVE, 0) == 1;
 	}
@@ -859,24 +591,6 @@ public class PlatformTorrentUtils
 		return getContentMapLong(torrent, TOR_AZ_PROP_MIN_SPEED, MIN_SPEED_DEFAULT);
 	}
 
-	/**
-	 * If either Ad Enabled or Web Ad Enabled is set return true.
-	 * @param torrent
-	 * @return - boolean - true if EITHER "Ad Enabled"==1  OR  "Web Ad Enabled"==1
-	 */
-	public static boolean isContentAdEnabled(TOTorrent torrent) {
-		return (getContentMapLong(torrent, TOR_AZ_PROP_AD_ENABLED, 0) == 1 ||
-				getContentMapLong(torrent, TOR_AZ_PROP_WEB_AD_ENABLED, 0) == 1);
-	}
-
-	public static boolean isContentUnitAdEnabled(TOTorrent torrent) {
-		return getContentMapLong(torrent, TOR_AZ_PROP_WEB_AD_ENABLED, 0) == 1;
-	}
-
-	public static boolean isContentWebAdEnabled(TOTorrent torrent) {
-		return getContentMapLong(torrent, TOR_AZ_PROP_WEB_AD_ENABLED, 0) == 1;
-	}
-
 	public static boolean useEMP(TOTorrent torrent) {
 		return getContentMapLong(torrent, TOR_AZ_PROP_USE_EMP, 0) == 1;
 	}
@@ -902,12 +616,6 @@ public class PlatformTorrentUtils
 		return l.longValue();
 	}
 
-	public static void setExpiresOn(TOTorrent torrent, long expiresOn) {
-		Map mapContent = getContentMap(torrent);
-		mapContent.put(TOR_AZ_PROP_EXPIRESON, new Long(expiresOn));
-		writeTorrentIfExists(torrent);
-	}
-
 	public static int getContentPrimaryFileIndex(TOTorrent torrent ){
 		return (int)getContentMapLong(torrent, TOR_AZ_PROP_PRIMARY_FILE, -1 );
 	}
@@ -925,6 +633,14 @@ public class PlatformTorrentUtils
 		return getContentMapLong(torrent, TOR_AZ_PROP_VIDEO_RUNNINGTIME, -1);
 	}
 	
+	public static long getContentDurationMillis(TOTorrent torrent) {
+		return getContentMapLong(torrent, TOR_AZ_PROP_DURATION_MILLIS, -1);
+	}
+	
+	public static void setContentDurationMillis(TOTorrent torrent, long millis ) {
+		setContentMapLong(torrent, TOR_AZ_PROP_DURATION_MILLIS, millis );
+	}
+	
 	public static int[] getContentVideoResolution(TOTorrent torrent) {
 		long width = getContentVideoWidth(torrent);
 		if (width <= 0) {
@@ -1027,10 +743,10 @@ public class PlatformTorrentUtils
 			return true;
 		}
 		boolean opened = getContentMapLong(torrent, TOR_AZ_PROP_OPENED, -1) > 0;
-		if (opened || getAdId(torrent) != null || isUpdateDM(dm)) {
+		if (opened || isUpdateDM(dm)) {
 			return true;
 		}
-		
+
 		return false;
 	}
 
diff --git a/com/aelitis/azureus/core/torrent/RatingInfoList.java b/com/aelitis/azureus/core/torrent/RatingInfoList.java
deleted file mode 100644
index 39661f4..0000000
--- a/com/aelitis/azureus/core/torrent/RatingInfoList.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Created on Mar 27, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.core.torrent;
-
-import com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger.GetRatingReply;
-
-/**
- * @author TuxPaper
- * @created Mar 27, 2008
- *
- */
-public abstract class RatingInfoList extends GetRatingReply
-{
-}
diff --git a/com/aelitis/azureus/core/torrent/SingleUserRatingInfo.java b/com/aelitis/azureus/core/torrent/SingleUserRatingInfo.java
deleted file mode 100644
index 973c220..0000000
--- a/com/aelitis/azureus/core/torrent/SingleUserRatingInfo.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Created on Mar 27, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.core.torrent;
-
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.torrent.TOTorrentException;
-
-/**
- * @author TuxPaper
- * @created Mar 27, 2008
- *
- */
-public class SingleUserRatingInfo
-	extends RatingInfoList
-{
-	private final TOTorrent torrent;
-
-	public SingleUserRatingInfo(TOTorrent torrent) {
-		this.torrent = torrent;
-	}
-
-	// @see com.aelitis.azureus.core.torrent.RatingInfoList#getRatingColor(java.lang.String, java.lang.String)
-	public String getRatingColor(String hash, String type) {
-		// not used for user rating
-		return null;
-	}
-
-	// @see com.aelitis.azureus.core.torrent.RatingInfoList#getRatingCount(java.lang.String, java.lang.String)
-	public long getRatingCount(String hash, String type) {
-		return 1;
-	}
-
-	// @see com.aelitis.azureus.core.torrent.RatingInfoList#getRatingExpireyMins(java.lang.String, java.lang.String)
-	public long getRatingExpireyMins(String hash, String type) {
-		// not used for user rating
-		return 0;
-	}
-
-	// @see com.aelitis.azureus.core.torrent.RatingInfoList#getRatingString(java.lang.String, java.lang.String)
-	public String getRatingString(String hash, String type) {
-		// not used for user rating
-		return "--";
-	}
-
-	// @see com.aelitis.azureus.core.torrent.RatingInfoList#getRatingValue(java.lang.String, java.lang.String)
-	public long getRatingValue(String hash, String type) {
-		if (!hasHash(hash)) {
-			return GlobalRatingUtils.RATING_NONE;
-		}
-		return PlatformTorrentUtils.getUserRating(torrent);
-	}
-
-	// @see com.aelitis.azureus.core.torrent.RatingInfoList#hasHash(java.lang.String)
-	public boolean hasHash(String hash) {
-		try {
-			return torrent.getHashWrapper().toBase32String().equals(hash);
-		} catch (TOTorrentException e) {
-			return false;
-		}
-	}
-}
diff --git a/com/aelitis/azureus/core/util/CopyOnWriteList.java b/com/aelitis/azureus/core/util/CopyOnWriteList.java
index d208597..74e8eb2 100644
--- a/com/aelitis/azureus/core/util/CopyOnWriteList.java
+++ b/com/aelitis/azureus/core/util/CopyOnWriteList.java
@@ -23,9 +23,14 @@
 package com.aelitis.azureus.core.util;
 
 import java.lang.ref.WeakReference;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 
-import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.core3.util.AEDiagnostics;
+import org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator;
+import org.gudy.azureus2.core3.util.IndentWriter;
 
 public class 
 CopyOnWriteList<T> 
@@ -35,7 +40,7 @@ implements Iterable<T>
 	
 	//private int mutation_count = 0;
 	
-	private List<T>	list = Collections.emptyList();
+	private List<T>	list = Collections.EMPTY_LIST;
 	
 	private boolean	visible = false;
 	
@@ -113,7 +118,7 @@ implements Iterable<T>
 				visible = false;
 				
 			}else{
-				if (list == Collections.emptyList()) {
+				if (list == Collections.EMPTY_LIST) {
 					list = new ArrayList<T>(initialCapacity);
 				}
 				
@@ -154,7 +159,7 @@ implements Iterable<T>
 	{
 		synchronized( this ){
 								
-			list	= Collections.emptyList();
+			list	= Collections.EMPTY_LIST;
 			
 			visible = false;
 		}
diff --git a/com/aelitis/azureus/core/util/CopyOnWriteMap.java b/com/aelitis/azureus/core/util/CopyOnWriteMap.java
index 7171363..f1bf096 100644
--- a/com/aelitis/azureus/core/util/CopyOnWriteMap.java
+++ b/com/aelitis/azureus/core/util/CopyOnWriteMap.java
@@ -31,7 +31,7 @@ public class CopyOnWriteMap {
 	private volatile Map map;
 	
 	public CopyOnWriteMap() {
-		this.map = new HashMap();
+		this.map = new HashMap(0);
 	}
 	
 	public void put(Object key, Object val) {
diff --git a/com/aelitis/azureus/core/util/FeatureAvailability.java b/com/aelitis/azureus/core/util/FeatureAvailability.java
index 83d3d3e..569c3c5 100644
--- a/com/aelitis/azureus/core/util/FeatureAvailability.java
+++ b/com/aelitis/azureus/core/util/FeatureAvailability.java
@@ -33,6 +33,7 @@ FeatureAvailability
 	private static final long	FT_DISABLE_PEER_UDP_RECONNECT		= 0x0000000000000004;
 	private static final long	FT_AUTO_SPEED_DEFAULT_CLASSIC		= 0x0000000000000008;
 	private static final long	FT_DISABLE_RCM						= 0x0000000000000010;
+	private static final long	FT_DISABLE_DHT_REP_V2				= 0x0000000000000020;
 	
 	private static VersionCheckClient vcc = VersionCheckClient.getSingleton();
 	
@@ -75,4 +76,12 @@ FeatureAvailability
 				
 		return( result );
 	}
+	
+	public static boolean
+	isDHTRepV2Enabled()
+	{
+		final boolean result = ( vcc.getFeatureFlags() & FT_DISABLE_DHT_REP_V2 ) == 0;
+				
+		return( result );
+	}
 }
diff --git a/com/aelitis/azureus/core/util/HTTPUtils.java b/com/aelitis/azureus/core/util/HTTPUtils.java
index 1f55cb5..c59d7f8 100644
--- a/com/aelitis/azureus/core/util/HTTPUtils.java
+++ b/com/aelitis/azureus/core/util/HTTPUtils.java
@@ -72,6 +72,8 @@ public class HTTPUtils {
 		file_types.put("mp4", "video/mp4");
 		file_types.put("mov", "video/quicktime");
 		file_types.put("avi", "video/avi");
+		
+		file_types.put("xap", "application/x-silverlight-app");
 
 		compression.add("text/html");
 		compression.add("text/css");
diff --git a/com/aelitis/azureus/core/util/MultiPartDecoder.java b/com/aelitis/azureus/core/util/MultiPartDecoder.java
new file mode 100644
index 0000000..2f32296
--- /dev/null
+++ b/com/aelitis/azureus/core/util/MultiPartDecoder.java
@@ -0,0 +1,392 @@
+/*
+ * Created on 23-Jun-2004
+ * Created by Paul Gardner
+ * Copyright (C) 2004 Aelitis, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * 
+ * AELITIS, SARL au capital de 30,000 euros
+ * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
+ *
+ */
+
+package com.aelitis.azureus.core.util;
+
+/**
+ * @author parg
+ *
+ */
+
+import java.io.*;
+import java.util.*;
+
+public class 
+MultiPartDecoder 
+{
+	public FormField[]
+	decode(
+		String			boundary,
+		InputStream		is )
+	
+		throws IOException
+	{
+		// -----------------------------7d4f2a310bca
+		//Content-Disposition: form-data; name="upfile"; filename="C:\Temp\banana_custard.torrent"
+		//Content-Type: application/octet-stream
+		//
+		// <data>
+		// -----------------------------7d4f2a310bca
+		// Content-Disposition: form-data; name="category"
+		//
+		//Music
+		// -----------------------------7d4f2a310bca--
+		
+		byte[]	header_end_bytes	= "\r\n\r\n".getBytes( "ISO-8859-1" );
+		
+		byte[]	boundary_bytes = (  "\r\n--" + boundary ).getBytes( "ISO-8859-1" );
+	
+		int	boundary_len = boundary_bytes.length;
+		
+		byte[]	buffer 		= new byte[65536];
+		int		buffer_pos	= 0;
+	
+		boolean	in_header	= true;
+	
+		byte[]	current_target 			= header_end_bytes;
+		int		current_target_length	= 4;
+		
+		FormField	current_field = null;
+		
+		List	fields = new ArrayList();
+		
+		while( true ){
+				
+			int	buffer_pos_start = buffer_pos;
+			
+			int	len = is.read( buffer, buffer_pos, buffer.length - buffer_pos );
+				
+			if ( len < 0 ){
+					
+				len	= 0;
+			}
+				
+			buffer_pos += len;
+	
+			boolean found_target = false;
+			
+			for (int i=0;i<=buffer_pos-current_target_length;i++){
+					
+				if ( buffer[i] == current_target[0] ){
+				
+					found_target	= true;
+					
+					for (int j=1;j<current_target_length;j++){
+							
+						if ( buffer[i+j] != current_target[j]){
+								
+							found_target = false;
+								
+							break;
+						}
+					}
+						
+					if ( found_target ){
+													
+						if ( in_header ){
+							
+							if ( current_field != null ){
+								
+								current_field.complete();
+							}
+							
+							String	header = new String( buffer, 0, i+4 );
+							
+							int	cdl_pos = header.toLowerCase().indexOf("content-disposition");
+							
+							if ( cdl_pos == -1 ){
+								
+								throw( new IOException( "invalid header '" + header + "'" ));
+							}
+							
+							int	cd_nl = header.indexOf( "\r\n", cdl_pos  );
+							
+							String	cd_line = header.substring( cdl_pos, cd_nl );
+							
+							int	cd_pos = 0;
+							
+							Map	attributes = new HashMap();
+							
+							while(true){
+								
+								int	p1 = cd_line.indexOf( ";", cd_pos );
+								
+								String	bit;
+								
+								if ( p1 == -1 ){
+									bit = cd_line.substring( cd_pos );
+								}else{
+									bit = cd_line.substring( cd_pos, p1 );
+									cd_pos = p1+1;
+								}
+							
+								int	ep = bit.indexOf( "=" );
+								
+								if ( ep != -1 ){
+								
+									String	lhs = bit.substring(0,ep).trim();
+									String	rhs = bit.substring(ep+1).trim();
+									
+									if ( rhs.startsWith("\"")){
+										
+										rhs = rhs.substring(1);
+									}
+									
+									if( rhs.endsWith("\"")){
+										rhs = rhs.substring(0,rhs.length()-1);
+									}
+									
+									attributes.put( lhs.toLowerCase(), rhs );
+								}
+								
+								if ( p1 == -1 ){
+									break;
+								}
+							}
+							
+							String	field_name = (String)attributes.get("name");
+							
+							if( field_name == null ){
+								
+								throw( new IOException( cd_line + " missing 'name' attribute" ));
+							}
+							current_field = new FormField( field_name, attributes );
+							
+							fields.add( current_field );
+							
+						}else{
+							
+							current_field.write( buffer, 0, i );
+						}
+						
+						int	rem = buffer_pos - (i+current_target_length);
+						
+						if ( rem > 0 ){
+							
+							System.arraycopy( buffer, i+current_target_length, buffer, 0, rem );
+						}
+						
+						buffer_pos	= rem;
+						
+						if ( in_header ){
+							
+							in_header	= false;
+							
+							current_target			= boundary_bytes;
+							current_target_length	= boundary_len;
+							
+						}else{
+							
+							in_header	= true;
+							
+							current_target 			= header_end_bytes;
+							current_target_length	= 4;
+						}
+						
+						break;
+					}
+				}
+			}		
+			
+				// if we didn't find the target and we're not in the header then
+				// any remaining data in the buffer (less current target length)
+				// is part of a body and can be written out
+			
+			if ( !(found_target || in_header )){
+				
+				int	rem = buffer_pos - current_target_length;
+				
+				if ( rem > 0 ){
+					
+						// process buffer 0 length rem
+										
+					current_field.write( buffer, 0, rem );
+					
+					System.arraycopy( buffer, rem, buffer, 0, current_target_length );
+				
+					buffer_pos = current_target_length;
+				}
+			}
+			
+			if ( len == 0 && buffer_pos == buffer_pos_start ){
+				
+					// nothing read and no progress made
+				
+				break;
+			}
+		}
+	
+			// should end in --
+		
+		if ( buffer_pos < 2 || buffer[0] != '-' || buffer[1] != '-' ){
+			
+			throw( new IOException( "Incorrect termination of form upload data"));
+		}
+		
+		current_field.complete();
+		
+		FormField[]	res = new FormField[fields.size()];
+		
+		fields.toArray( res );
+			
+		return( res );
+	}
+	
+	public static class
+	FormField
+	{
+		protected String		name;
+		protected Map			attributes;
+		
+		protected long			total_len;
+		
+		ByteArrayOutputStream	baos = new ByteArrayOutputStream(1024);
+		
+		File					file;
+		FileOutputStream		fos;
+		
+		InputStream				returned_stream;
+		
+		protected
+		FormField(
+			String		_name,
+			Map			_attributes )
+		{
+			name		= _name;
+			attributes	= _attributes;
+			
+			// System.out.println( "formField:" + name );
+		}
+		
+		public String
+		getName()
+		{
+			return( name );
+		}
+		
+		public String
+		getAttribute(
+			String	attr_name )
+		{
+			return((String)attributes.get(attr_name.toLowerCase()));
+		}
+		
+		public InputStream
+		getInputStream()
+		
+			throws IOException
+		{
+			if ( file == null ){
+				
+				returned_stream = new ByteArrayInputStream( baos.toByteArray());
+				
+			}else{
+			
+				returned_stream = new FileInputStream( file );
+			}
+			
+			return( returned_stream );
+		}
+		
+		public String
+		getString()
+		
+			throws IOException
+		{
+			String	str = new LineNumberReader(new InputStreamReader( getInputStream())).readLine();
+			
+			if ( str == null ){
+				
+				str = "";
+			}
+			
+			return( str );
+		}
+		
+		public void
+		destroy()
+		{
+			if ( returned_stream != null ){
+				
+				try{
+					returned_stream.close();
+					
+				}catch( Throwable e ){
+					
+				}
+			}
+			
+			if ( file != null ){
+				
+				file.delete();
+			}
+		}
+		
+		protected void
+		write(
+			byte[]		buffer,
+			int			start,
+			int			len )
+		
+			throws IOException
+		{
+			total_len	+= len;
+		
+			if ( fos != null ){
+				
+				fos.write( buffer, start, len );
+				
+			}else{
+			
+				if ( total_len > 1024 ){
+			
+					file	= File.createTempFile( "AZU", null );
+					
+					file.deleteOnExit();
+					
+					fos = new FileOutputStream( file );
+					
+					fos.write( baos.toByteArray());
+					
+					fos.write( buffer, start, len );
+					
+				}else{
+					
+					baos.write( buffer, start, len );
+				}
+			}
+		}
+		
+		protected void
+		complete()
+		
+			throws IOException
+		{
+			// System.out.println( "    total_len = " + total_len );
+			
+			if ( fos != null ){
+				
+				fos.close();
+			}
+		}
+	}
+}
diff --git a/com/aelitis/azureus/core/util/bloom/BloomFilter.java b/com/aelitis/azureus/core/util/bloom/BloomFilter.java
index c93e16d..b34ac22 100644
--- a/com/aelitis/azureus/core/util/bloom/BloomFilter.java
+++ b/com/aelitis/azureus/core/util/bloom/BloomFilter.java
@@ -22,6 +22,8 @@
 
 package com.aelitis.azureus.core.util.bloom;
 
+import java.util.Map;
+
 public interface 
 BloomFilter 
 {
@@ -60,6 +62,9 @@ BloomFilter
 	public BloomFilter
 	getReplica();
 	
+	public Map<String,Object>
+	serialiseToMap();
+	
 	public String
 	getString();
 }
diff --git a/com/aelitis/azureus/core/util/bloom/BloomFilterFactory.java b/com/aelitis/azureus/core/util/bloom/BloomFilterFactory.java
index 6600f63..f3552b5 100644
--- a/com/aelitis/azureus/core/util/bloom/BloomFilterFactory.java
+++ b/com/aelitis/azureus/core/util/bloom/BloomFilterFactory.java
@@ -22,6 +22,8 @@
 
 package com.aelitis.azureus.core.util.bloom;
 
+import java.util.Map;
+
 import com.aelitis.azureus.core.util.bloom.impl.*;
 
 public class 
@@ -69,4 +71,11 @@ BloomFilterFactory
 			return( new BloomFilterRotator( basis, number ));
 		}
 	}
+	
+	public static BloomFilter
+	deserialiseFromMap(
+		Map<String,Object>	map )
+	{
+		return( BloomFilterImpl.deserialiseFromMap(map));
+	}
 }
diff --git a/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddOnly.java b/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddOnly.java
index 7a11992..c844324 100644
--- a/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddOnly.java
+++ b/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddOnly.java
@@ -22,6 +22,8 @@
 
 package com.aelitis.azureus.core.util.bloom.impl;
 
+import java.util.Map;
+
 import com.aelitis.azureus.core.util.bloom.BloomFilter;
 
 public class 
@@ -39,6 +41,24 @@ BloomFilterAddOnly
 		map	= new byte[(getMaxEntries()+7)/8];
 	}
 	
+	public
+	BloomFilterAddOnly(
+		Map<String,Object>		x )
+	{
+		super( x );
+		
+		map = (byte[])x.get( "map" );
+	}
+	
+	protected void
+	serialiseToMap(
+		Map<String,Object>		x )
+	{
+		super.serialiseToMap( x );
+		
+		x.put( "map", map.clone());
+	}
+	
 	public BloomFilter 
 	getReplica() 
 	{
diff --git a/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddRemove4Bit.java b/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddRemove4Bit.java
index a5f7073..cd63e62 100644
--- a/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddRemove4Bit.java
+++ b/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddRemove4Bit.java
@@ -22,6 +22,8 @@
 
 package com.aelitis.azureus.core.util.bloom.impl;
 
+import java.util.Map;
+
 import com.aelitis.azureus.core.util.bloom.BloomFilter;
 
 public class 
@@ -41,6 +43,24 @@ BloomFilterAddRemove4Bit
 		map	= new byte[(getMaxEntries()+1)/2];
 	}
 	
+	public
+	BloomFilterAddRemove4Bit(
+		Map<String,Object>		x )
+	{
+		super( x );
+		
+		map = (byte[])x.get( "map" );
+	}
+	
+	protected void
+	serialiseToMap(
+		Map<String,Object>		x )
+	{
+		super.serialiseToMap( x );
+		
+		x.put( "map", map.clone());
+	}
+	
 	public BloomFilter 
 	getReplica() 
 	{
diff --git a/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddRemove8Bit.java b/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddRemove8Bit.java
index e1e2bb2..06ae980 100644
--- a/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddRemove8Bit.java
+++ b/com/aelitis/azureus/core/util/bloom/impl/BloomFilterAddRemove8Bit.java
@@ -22,6 +22,8 @@
 
 package com.aelitis.azureus.core.util.bloom.impl;
 
+import java.util.Map;
+
 import com.aelitis.azureus.core.util.bloom.BloomFilter;
 
 public class 
@@ -39,6 +41,24 @@ BloomFilterAddRemove8Bit
 		map	= new byte[getMaxEntries()];
 	}
 	
+	public
+	BloomFilterAddRemove8Bit(
+		Map<String,Object>		x )
+	{
+		super( x );
+		
+		map = (byte[])x.get( "map" );
+	}
+	
+	protected void
+	serialiseToMap(
+		Map<String,Object>		x )
+	{
+		super.serialiseToMap( x );
+		
+		x.put( "map", map.clone());
+	}
+	
 	public BloomFilter 
 	getReplica() 
 	{
diff --git a/com/aelitis/azureus/core/util/bloom/impl/BloomFilterImpl.java b/com/aelitis/azureus/core/util/bloom/impl/BloomFilterImpl.java
index 7318a04..f49823a 100644
--- a/com/aelitis/azureus/core/util/bloom/impl/BloomFilterImpl.java
+++ b/com/aelitis/azureus/core/util/bloom/impl/BloomFilterImpl.java
@@ -22,14 +22,23 @@
 
 package com.aelitis.azureus.core.util.bloom.impl;
 
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Random;
 
+import org.gudy.azureus2.core3.util.Debug;
+
 import com.aelitis.azureus.core.util.bloom.BloomFilter;
+import com.aelitis.azureus.util.MapUtils;
+
 
 public abstract class 
 BloomFilterImpl
 	implements BloomFilter
 {
+	protected static final String MY_PACKAGE = "com.aelitis.azureus.core.util.bloom.impl";
+
 	/*
 	private static final boolean	USE_BIG_INTS	= false;
 	private static final char[]	HEX_CHARS = "0123456789ABCDEF".toCharArray();
@@ -55,7 +64,33 @@ BloomFilterImpl
 	private static final int	b3		= 145;
 	private static final int	b4		= 216;
 	
+	public static BloomFilter
+	deserialiseFromMap(
+		Map<String,Object>	map )
+	{
+		String	impl = MapUtils.getMapString( map, "_impl", "" );
+		
+		if ( impl.startsWith( "." )){
+			
+			impl = MY_PACKAGE + impl;
+		}
+		
+		try{
+			Class<BloomFilterImpl> cla = (Class<BloomFilterImpl>)Class.forName( impl );
+			
+			Constructor<BloomFilterImpl> cons = cla.getDeclaredConstructor( Map.class );
+			
+			cons.setAccessible( true );
+			
+			return( cons.newInstance( map ));
+			
+		}catch( Throwable e ){
 
+			Debug.out( "Can't construct bloom filter for " + impl, e );
+			
+			return( null );
+		}
+	}
 	
 
 	private int			max_entries;
@@ -72,6 +107,41 @@ BloomFilterImpl
 		max_entries	= ((_max_entries/2)*2)+1;
 	}
 	
+	public
+	BloomFilterImpl(
+		Map<String,Object>		x )
+	{
+		max_entries = ((Long)x.get( "_max" )).intValue();
+		
+		entry_count = ((Long)x.get( "_count" )).intValue();
+	}
+	protected void
+	serialiseToMap(
+		Map<String,Object>		x )
+	{
+		String	cla = this.getClass().getName();
+		
+		if ( cla.startsWith( MY_PACKAGE )){
+			
+			cla = cla.substring( MY_PACKAGE.length());
+		}
+		
+		x.put( "_impl", cla );
+		
+		x.put( "_max", new Long( max_entries ));
+		x.put( "_count", new Long( entry_count ));
+	}
+	
+	public Map<String, Object> 
+	serialiseToMap() 
+	{
+		Map<String, Object>  m = new HashMap<String, Object>();
+		
+		serialiseToMap( m );
+		
+		return( m );
+	}
+	
 	protected int
 	getMaxEntries()
 	{
diff --git a/com/aelitis/azureus/core/util/bloom/impl/BloomFilterRotator.java b/com/aelitis/azureus/core/util/bloom/impl/BloomFilterRotator.java
index 810faf5..b9f4eda 100644
--- a/com/aelitis/azureus/core/util/bloom/impl/BloomFilterRotator.java
+++ b/com/aelitis/azureus/core/util/bloom/impl/BloomFilterRotator.java
@@ -21,6 +21,11 @@
 
 package com.aelitis.azureus.core.util.bloom.impl;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import com.aelitis.azureus.core.util.bloom.BloomFilter;
 
 public class 
@@ -50,6 +55,58 @@ BloomFilterRotator
 		current_filter_index	= 0;
 	}
 	
+	public
+	BloomFilterRotator(
+		Map<String,Object>		x )
+	{
+		List<Map<String,Object>>	list = (List<Map<String,Object>>)x.get( "list" );
+		
+		filters = new BloomFilter[ list.size() ];
+		
+		for (int i=0;i<filters.length;i++){
+			
+			filters[i] = BloomFilterImpl.deserialiseFromMap( list.get(i));
+		}
+		
+		current_filter_index = ((Long)x.get( "index" )).intValue();
+		
+		current_filter = filters[ current_filter_index ];
+	}
+	
+	public Map<String, Object> 
+	serialiseToMap() 
+	{
+		Map<String, Object>  m = new HashMap<String, Object>();
+		
+		serialiseToMap( m );
+		
+		return( m );
+	}
+	
+	protected void
+	serialiseToMap(
+		Map<String,Object>		x )
+	{
+		String	cla = this.getClass().getName();
+		
+		if ( cla.startsWith( BloomFilterImpl.MY_PACKAGE )){
+			
+			cla = cla.substring( BloomFilterImpl.MY_PACKAGE.length());
+		}
+		
+		x.put( "_impl", cla );
+		
+		List<Map<String,Object>>	list = new ArrayList<Map<String,Object>>();
+		
+		for ( BloomFilter filter: filters ){
+			
+			list.add( filter.serialiseToMap());
+		}
+		
+		x.put( "list", list );
+		x.put( "index", new Long( current_filter_index ));
+	}
+	
 	public int
 	add(
 		byte[]		value )
diff --git a/com/aelitis/azureus/core/versioncheck/VersionCheckClient.java b/com/aelitis/azureus/core/versioncheck/VersionCheckClient.java
index ce7359b..0ff3592 100644
--- a/com/aelitis/azureus/core/versioncheck/VersionCheckClient.java
+++ b/com/aelitis/azureus/core/versioncheck/VersionCheckClient.java
@@ -42,6 +42,8 @@ import org.gudy.azureus2.core3.stats.transfer.*;
 import org.gudy.azureus2.core3.util.*;
 
 import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.utils.DelayedTask;
+import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
@@ -150,6 +152,44 @@ public class VersionCheckClient {
 			  });
   }
   
+  public void
+  initialise()
+  {
+	  DelayedTask delayed_task = 
+		  UtilitiesImpl.addDelayedTask(
+	   		"VersionCheck", 
+	   		new Runnable()
+	   		{
+	   			public void
+	   			run()
+	   			{
+	   				final AESemaphore sem = new AESemaphore( "VCC:init" );
+	   				
+	   				new AEThread2( "VCC:init", true )
+	   				{
+	   					public void 
+	   					run()
+	   					{
+	   						try{
+	   							getVersionCheckInfo( REASON_UPDATE_CHECK_START );
+	   							
+	   						}finally{
+	   							
+	   							sem.release();
+	   						}
+	   					}
+	   				}.start();
+	   				
+	   				if ( !sem.reserve( 5000 )){
+	   					
+	   					Debug.out( "Timeout waiting for version check to complete" );
+	   				}
+	   			}
+	   		});
+	  
+	  delayed_task.queue();
+  }
+  
   
   
    
@@ -317,6 +357,8 @@ public class VersionCheckClient {
 	    
 	    if( last_check_data_v4 == null )  last_check_data_v4 = new HashMap();
 	    
+	    last_feature_flag_cache_time = 0;
+	    
 	    return last_check_data_v4;
   	}
   }
@@ -532,38 +574,39 @@ public class VersionCheckClient {
 	Exception 	error 	= null;
 	Map			reply	= null;
 	
-	if ( use_az_message ){
 	
+	if ( use_http ){
+		
 		try{
-			reply = executeAZMessage( data_to_send, v6 );
+			reply = executeHTTP( data_to_send, v6 );
 			
-			reply.put( "protocol_used", "AZMSG" );
+			reply.put( "protocol_used", "HTTP" );
+			
+			error = null;
 		}
 		catch (IOException e) {
 			error = e;
 		}
-		catch (Exception e) {
-			Debug.printStackTrace( e );
+		catch (Exception e){
+			Debug.printStackTrace(e);
 			error = e;
+			
 		}
 	}
 	
-	if ( reply == null && use_http ){
+	if ( reply == null && use_az_message ){
 		
 		try{
-			reply = executeHTTP( data_to_send, v6 );
-			
-			reply.put( "protocol_used", "HTTP" );
+			reply = executeAZMessage( data_to_send, v6 );
 			
-			error = null;
+			reply.put( "protocol_used", "AZMSG" );
 		}
 		catch (IOException e) {
 			error = e;
 		}
-		catch (Exception e){
-			Debug.printStackTrace(e);
+		catch (Exception e) {
+			Debug.printStackTrace( e );
 			error = e;
-			
 		}
 	}
 	if ( error != null ){
diff --git a/com/aelitis/azureus/jdk15/Java15Initialiser.java b/com/aelitis/azureus/jdk15/Java15Initialiser.java
index 9aadb55..aa40905 100644
--- a/com/aelitis/azureus/jdk15/Java15Initialiser.java
+++ b/com/aelitis/azureus/jdk15/Java15Initialiser.java
@@ -43,7 +43,7 @@ Java15Initialiser
 				
 				AEThreadMonitor.initialise();
 	
-				VivaldiV2PositionProvider.initialise();
+				// VivaldiV2PositionProvider.initialise();
 				
 			}catch( Throwable e ){
 				
diff --git a/com/aelitis/azureus/login/NotLoggedInException.java b/com/aelitis/azureus/login/NotLoggedInException.java
deleted file mode 100644
index 999f9d9..0000000
--- a/com/aelitis/azureus/login/NotLoggedInException.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * Created on May 5, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
- 
-package com.aelitis.azureus.login;
-
-/**
- * @author TuxPaper
- * @created May 5, 2008
- *
- */
-public class NotLoggedInException
-	extends Exception
-{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -6339467293256114226L;
-
-	/**
-	 * 
-	 */
-	public NotLoggedInException() {
-		super();
-		// TODO Auto-generated constructor stub
-	}
-
-	/**
-	 * @param message
-	 * @param cause
-	 */
-	public NotLoggedInException(String message, Throwable cause) {
-		super(message, cause);
-		// TODO Auto-generated constructor stub
-	}
-
-	/**
-	 * @param message
-	 */
-	public NotLoggedInException(String message) {
-		super(message);
-		// TODO Auto-generated constructor stub
-	}
-
-	/**
-	 * @param cause
-	 */
-	public NotLoggedInException(Throwable cause) {
-		super(cause);
-		// TODO Auto-generated constructor stub
-	}
-
-}
diff --git a/com/aelitis/azureus/plugins/dht/DHTPlugin.java b/com/aelitis/azureus/plugins/dht/DHTPlugin.java
index fd79be7..e8953a2 100644
--- a/com/aelitis/azureus/plugins/dht/DHTPlugin.java
+++ b/com/aelitis/azureus/plugins/dht/DHTPlugin.java
@@ -24,6 +24,9 @@ package com.aelitis.azureus.plugins.dht;
 
 
 
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.*;
 
@@ -371,10 +374,10 @@ DHTPlugin
 											
 											for ( Map.Entry<Byte, Integer> entry: counts.entrySet()){
 											
-												ver += (ver.length()==0?"":", " ) + entry.getKey() + "=" + 100*entry.getValue()/total;
+												ver += (ver.length()==0?"":", " ) + entry.getKey() + "=" + 100*entry.getValue()/total + "%";
 											}
 											
-											log.log( "    " + ver );
+											log.log( "    contacts=" + total + ": " + ver );
 										}
 									}else if ( lc.equals( "testca" )){
 																
@@ -1218,7 +1221,12 @@ DHTPlugin
 	getLocalValue(
 		byte[]		key )
 	{
-		return( main_dht.getLocalValue( key ));
+		if ( main_dht != null ){
+			
+			return( main_dht.getLocalValue( key ));
+		}
+		
+		return( cvs_dht.getLocalValue( key ));
 	}
 	
 	public void
@@ -1245,6 +1253,15 @@ DHTPlugin
 			
 		}else{
 			
+			if ( main_dht == null && main_v6_dht == null ){
+				
+					// just the cvs dht
+				
+				cvs_dht.get( original_key, description, flags, max_values, timeout, exhaustive, high_priority, original_listener );
+
+				return;
+			}
+			
 				// hook into CVS completion to prevent runaway CVS dht operations
 			
 			final int[]		completes_to_go = { 2 };
@@ -1689,6 +1706,32 @@ DHTPlugin
 	}
 	
 	public DHTPluginContact
+	importContact(
+		InetSocketAddress				address,
+		byte							version )
+	{
+		if ( !isEnabled()){
+			
+			throw( new RuntimeException( "DHT isn't enabled" ));
+		}
+
+		InetAddress contact_address = address.getAddress();
+		
+		for ( DHTPluginImpl dht: dhts ){
+			
+			InetAddress dht_address = dht.getLocalAddress().getAddress().getAddress();
+			
+			if ( 	( contact_address instanceof Inet4Address && dht_address instanceof Inet4Address ) ||
+					( contact_address instanceof Inet6Address && dht_address instanceof Inet6Address )){
+				
+				return( dht.importContact( address, version ));
+			}
+		}
+		
+		return( null );
+	}
+	
+	public DHTPluginContact
 	getLocalAddress()
 	{
 		if ( !isEnabled()){
diff --git a/com/aelitis/azureus/plugins/dht/DHTPluginContact.java b/com/aelitis/azureus/plugins/dht/DHTPluginContact.java
index d8d2fcd..3eed59f 100644
--- a/com/aelitis/azureus/plugins/dht/DHTPluginContact.java
+++ b/com/aelitis/azureus/plugins/dht/DHTPluginContact.java
@@ -47,6 +47,11 @@ DHTPluginContact
 	isAlive(
 		long		timeout );
 	
+	public void
+	isAlive(
+		long						timeout,
+		DHTPluginOperationListener	listener );
+	
 	public boolean
 	isOrHasBeenLocal();
 	
diff --git a/com/aelitis/azureus/plugins/dht/impl/DHTPluginContactImpl.java b/com/aelitis/azureus/plugins/dht/impl/DHTPluginContactImpl.java
index 3389320..0513dce 100644
--- a/com/aelitis/azureus/plugins/dht/impl/DHTPluginContactImpl.java
+++ b/com/aelitis/azureus/plugins/dht/impl/DHTPluginContactImpl.java
@@ -27,7 +27,9 @@ import java.util.Map;
 
 import com.aelitis.azureus.core.dht.nat.DHTNATPuncher;
 import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
+import com.aelitis.azureus.core.dht.transport.DHTTransportReplyHandlerAdapter;
 import com.aelitis.azureus.plugins.dht.DHTPluginContact;
+import com.aelitis.azureus.plugins.dht.DHTPluginOperationListener;
 import com.aelitis.azureus.plugins.dht.DHTPluginProgressListener;
 
 public class
@@ -83,6 +85,32 @@ DHTPluginContactImpl
 		return( contact.isAlive( timeout ));
 	}
 	
+	public void
+	isAlive(
+		long								timeout,
+		final DHTPluginOperationListener	listener )
+	{
+		contact.isAlive( 
+			new DHTTransportReplyHandlerAdapter()
+			{
+				public void
+				pingReply(
+					DHTTransportContact contact )
+				{
+					listener.complete( null, false );
+				}
+				
+				public void 
+				failed(
+					DHTTransportContact 	contact, 
+					Throwable 				error ) 
+				{
+					listener.complete( null, true );
+				}
+			},
+			timeout );
+	}
+	
 	public boolean
 	isOrHasBeenLocal()
 	{
diff --git a/com/aelitis/azureus/plugins/dht/impl/DHTPluginImpl.java b/com/aelitis/azureus/plugins/dht/impl/DHTPluginImpl.java
index ecedc25..31f3cdd 100644
--- a/com/aelitis/azureus/plugins/dht/impl/DHTPluginImpl.java
+++ b/com/aelitis/azureus/plugins/dht/impl/DHTPluginImpl.java
@@ -715,7 +715,8 @@ outer:
 						
 						public void
 						found(
-							DHTTransportContact	contact )
+							DHTTransportContact	contact,
+							boolean				is_closest )
 						{
 						}
 
@@ -819,7 +820,8 @@ outer:
 						
 						public void
 						found(
-							DHTTransportContact	contact )
+							DHTTransportContact	contact,
+							boolean				is_closest )
 						{
 						}
 
@@ -894,7 +896,8 @@ outer:
 		
 							public void
 							found(
-								DHTTransportContact	contact )
+								DHTTransportContact	contact,
+								boolean				is_closest )
 							{
 							}
 
@@ -983,7 +986,8 @@ outer:
 							
 							public void
 							found(
-								DHTTransportContact	contact )
+								DHTTransportContact	contact,
+								boolean				is_closest )
 							{
 							}
 
@@ -1048,6 +1052,22 @@ outer:
 		}
 	}
 	
+	public DHTPluginContact
+	importContact(
+		InetSocketAddress				address,
+		byte							version )
+	{
+		try{
+			return( new DHTPluginContactImpl( this, transport.importContact( address, version )));
+			
+		}catch( DHTTransportException	e ){
+			
+			Debug.printStackTrace(e);
+			
+			return( null );
+		}
+	}
+	
 		// direct read/write support
 	
 	public void
diff --git a/com/aelitis/azureus/plugins/dht/impl/DHTPluginStorageManager.java b/com/aelitis/azureus/plugins/dht/impl/DHTPluginStorageManager.java
index fbef893..1643fc5 100644
--- a/com/aelitis/azureus/plugins/dht/impl/DHTPluginStorageManager.java
+++ b/com/aelitis/azureus/plugins/dht/impl/DHTPluginStorageManager.java
@@ -817,6 +817,7 @@ DHTPluginStorageManager
 	
 	public byte[][]
 	createNewDiversification(
+		String				description,
 		DHTTransportContact	cause,
 		byte[]				key,
 		boolean				put_operation,
@@ -832,7 +833,7 @@ DHTPluginStorageManager
 			}
 		}
 		
-		//System.out.println( "DHT create new diversification: put = " + put_operation +", type = " + diversification_type );
+		// System.out.println( "DHT create new diversification: desc=" + description + ", put=" + put_operation +", type=" + diversification_type );
 		
 		HashWrapper	wrapper = new HashWrapper( key );
 		
@@ -860,10 +861,11 @@ DHTPluginStorageManager
 			}
 			
 			log.log( "SM: create div: " + DHTLog.getString2(key) + 
-						", new = " + created + ", put = " + put_operation + 
-						", exh = " + exhaustive + 
-						", type = " + DHT.DT_STRINGS[diversification_type] + " -> " + trace +
-						", cause = " + (cause==null?"<unknown>":cause.getString()));
+						", new=" + created + ", put = " + put_operation + 
+						", exh=" + exhaustive + 
+						", type=" + DHT.DT_STRINGS[diversification_type] + " -> " + trace +
+						", cause=" + (cause==null?"<unknown>":cause.getString()) +
+						", desc=" + description );
 			
 
 			return( res );
diff --git a/com/aelitis/azureus/plugins/extseed/ExternalSeedPlugin.java b/com/aelitis/azureus/plugins/extseed/ExternalSeedPlugin.java
index 35d8503..24d09a8 100644
--- a/com/aelitis/azureus/plugins/extseed/ExternalSeedPlugin.java
+++ b/com/aelitis/azureus/plugins/extseed/ExternalSeedPlugin.java
@@ -37,6 +37,7 @@ import org.gudy.azureus2.plugins.logging.LoggerChannel;
 import org.gudy.azureus2.plugins.logging.LoggerChannelListener;
 import org.gudy.azureus2.plugins.peers.PeerManager;
 import org.gudy.azureus2.plugins.torrent.Torrent;
+import org.gudy.azureus2.plugins.ui.components.UITextField;
 import org.gudy.azureus2.plugins.ui.model.BasicPluginViewModel;
 import org.gudy.azureus2.plugins.utils.*;
 
@@ -54,6 +55,8 @@ ExternalSeedPlugin
 	
 	private PluginInterface			plugin_interface;
 	private DownloadManagerStats	dm_stats;
+	
+	private UITextField				status_field;
 	private LoggerChannel			log;
 	
 	private 		Random	random = new Random();
@@ -118,6 +121,10 @@ ExternalSeedPlugin
 					}
 				});		
 		
+		status_field = view_model.getStatus();
+		
+		setStatus( "Initialising" );
+		
 		download_mon	= plugin_interface.getUtilities().getMonitor();
 		
 		Utilities utilities = plugin_interface.getUtilities();
@@ -133,8 +140,9 @@ ExternalSeedPlugin
 							public void 
 							run() 
 							{
-								plugin_interface.getDownloadManager().addListener(
-										ExternalSeedPlugin.this);
+								setStatus( "Running" );
+								
+								plugin_interface.getDownloadManager().addListener( ExternalSeedPlugin.this);
 							}
 						};
 					
@@ -220,6 +228,15 @@ ExternalSeedPlugin
 	}
 		
 	public void
+	downloadChanged(
+		Download	download )
+	{
+		downloadRemoved( download );
+		
+		downloadAdded( download );
+	}
+	
+	public void
 	addSeed(
 		Download	download,
 		Map			config )
@@ -311,6 +328,8 @@ ExternalSeedPlugin
 				}
 				
 				
+				setStatus( "Running: Downloads with external seeds = " + download_map.size());
+				
 			}finally{
 				
 				download_mon.exit();
@@ -440,6 +459,8 @@ ExternalSeedPlugin
 			
 			download_map.remove( download );
 			
+			setStatus( "Running: Downloads with external seeds = " + download_map.size());
+			
 		}finally{
 			
 			download_mon.exit();
@@ -476,6 +497,13 @@ ExternalSeedPlugin
 		return( dm_stats.getDataAndProtocolReceiveRate());
 	}
 	
+	protected void
+	setStatus(
+		String		str )
+	{
+		status_field.setText( str );
+	}
+	
 	public void
 	log(
 		String		str )
diff --git a/com/aelitis/azureus/plugins/extseed/ExternalSeedReader.java b/com/aelitis/azureus/plugins/extseed/ExternalSeedReader.java
index d835673..d190c93 100644
--- a/com/aelitis/azureus/plugins/extseed/ExternalSeedReader.java
+++ b/com/aelitis/azureus/plugins/extseed/ExternalSeedReader.java
@@ -69,7 +69,7 @@ ExternalSeedReader
 	
 	public void
 	addRequests(
-		List			requests );
+		List<PeerReadRequest>			requests );
 	
 	public void
 	cancelRequest(
@@ -92,10 +92,10 @@ ExternalSeedReader
 	public int
 	getRequestCount();
 	
-	public List
+	public List<PeerReadRequest>
 	getExpiredRequests();
 	
-	public List
+	public List<PeerReadRequest>
 	getRequests();
 	
 	public int
diff --git a/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderImpl.java b/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderImpl.java
index 206e86a..0d063e1 100644
--- a/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderImpl.java
+++ b/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderImpl.java
@@ -60,6 +60,7 @@ ExternalSeedReaderImpl
 	public static final int STALLED_DOWNLOAD_SPEED		= 20*1024;
 	public static final int STALLED_PEER_SPEED			= 5*1024;
 	
+	public static final int TOP_PIECE_PRIORITY			= 100*1000;
 
 	private ExternalSeedPlugin	plugin;
 	private Torrent				torrent;
@@ -78,7 +79,9 @@ ExternalSeedReaderImpl
 	
 	private volatile PeerManager		current_manager;
 		
-	private List			requests		= new LinkedList();
+	private List<PeerReadRequest>			requests			= new LinkedList<PeerReadRequest>();
+	private List<PeerReadRequest>			dangling_requests;
+
 	private Thread			request_thread;
 	private Semaphore		request_sem;
 	private Monitor			requests_mon;
@@ -87,6 +90,7 @@ ExternalSeedReaderImpl
 	
 	private int[]		priority_offsets;
 	
+	private boolean		fast_activate;
 	private int			min_availability;
 	private int			min_speed;
 	private long		valid_until;
@@ -112,7 +116,8 @@ ExternalSeedReaderImpl
 	{
 		plugin	= _plugin;
 		torrent	= _torrent;
-		
+				
+		fast_activate 		= getBooleanParam( _params, "fast_start", false );
 		min_availability 	= getIntParam( _params, "min_avail", 1 );	// default is avail based
 		min_speed			= getIntParam( _params, "min_speed", 0 );
 		valid_until			= getIntParam( _params, "valid_ms", 0 );
@@ -145,7 +150,7 @@ ExternalSeedReaderImpl
 		}catch( Throwable e ){
 		}
 			
-		setActive( false );
+		setActive( null, false );
 	}
 	
 	public Torrent
@@ -366,7 +371,7 @@ ExternalSeedReaderImpl
 			
 				// availability and speed based stuff needs a little time before being applied
 			
-			if ( !early_days ){
+			if ( fast_activate || !early_days ){
 				
 				if ( min_availability > 0 ){
 										
@@ -423,15 +428,18 @@ ExternalSeedReaderImpl
 				return( false );
 			}
 			
+			boolean	deactivate = false;
+			String	reason		= "";
+			
 			if ( min_availability > 0 ){
 
 				float availability = peer_manager.getDownload().getStats().getAvailability();
 			
 				if ( availability >= min_availability + 1 ){
 				
-					log( getName() + ": deactivating as availability is good" );
+					reason =  "availability is good";
 				
-					return( true );
+					deactivate = true;
 				}
 			}
 			
@@ -443,11 +451,21 @@ ExternalSeedReaderImpl
 				
 				if ( overall_speed - my_speed > 2 * min_speed ){
 					
-					log( getName() + ": deactivating as speed is good" );
+					reason += (reason.length()==0?"":", ") + "speed is good";
 
-					return( true );
+					deactivate = true;
+					
+				}else{
+					
+					deactivate = false;
 				}
+			}
+			
+			if ( deactivate ){
 				
+				log( getName() + ": deactivating as " + reason );
+
+				return( true );
 			}
 		}catch( Throwable e ){
 			
@@ -480,7 +498,7 @@ ExternalSeedReaderImpl
 					
 					if ( now - peer_manager_change_time > INITIAL_DELAY && readyToDeactivate( peer_manager, peer )){
 													
-						setActive( false );			
+						setActive( peer_manager, false );			
 					}
 				}else{
 					
@@ -488,7 +506,7 @@ ExternalSeedReaderImpl
 					
 						if ( readyToActivate( peer_manager, peer, time_since_started )){
 							
-							setActive( true );				
+							setActive( peer_manager, true );				
 						}
 					}
 				}
@@ -500,6 +518,8 @@ ExternalSeedReaderImpl
 			
 			peer_manager_change_time	= now;
 			
+			PeerManager existing_manager = current_manager;
+			
 			if ( current_manager != null ){
 				
 				current_manager.removeListener( this );
@@ -512,7 +532,7 @@ ExternalSeedReaderImpl
 				current_manager.addListener( this );
 			}
 			
-			setActive( false );
+			setActive( existing_manager, false );
 		}
 		
 		return( active );
@@ -529,6 +549,7 @@ ExternalSeedReaderImpl
 	
 	protected void
 	setActive(
+		PeerManager	_peer_manager,
 		boolean		_active )
 	{
 		try{
@@ -538,12 +559,22 @@ ExternalSeedReaderImpl
 			
 			status = active?"Active":"Idle";
 			
+			setActiveSupport( _peer_manager, _active );
+			
 		}finally{
 			
 			requests_mon.exit();
 		}
 	}
 	
+	protected void
+	setActiveSupport(
+		PeerManager	_peer_manager,
+		boolean		_active )
+	{
+		// overridden if needed
+	}
+	
 	public boolean
 	isActive()
 	{
@@ -578,6 +609,8 @@ ExternalSeedReaderImpl
 						
 						if ( requests.size() == 0 ){
 							
+							dangling_requests = null;
+							
 							request_thread	= null;
 							
 							break;
@@ -588,8 +621,8 @@ ExternalSeedReaderImpl
 					}
 				}else{
 					
-					List			selected_requests 	= new ArrayList();
-					PeerReadRequest	cancelled_request	= null;
+					List<PeerReadRequest>	selected_requests 	= new ArrayList<PeerReadRequest>();
+					PeerReadRequest			cancelled_request	= null;
 					
 					try{
 						requests_mon.enter();
@@ -607,7 +640,7 @@ ExternalSeedReaderImpl
 						
 						for (int i=0;i<count;i++){
 							
-							PeerReadRequest	request = (PeerReadRequest)requests.remove(0);
+							PeerReadRequest	request = requests.remove(0);
 							
 							if ( request.isCancelled()){
 								
@@ -638,6 +671,8 @@ ExternalSeedReaderImpl
 							}
 						}
 						
+						dangling_requests = new ArrayList<PeerReadRequest>( selected_requests );
+						
 					}finally{
 						
 						requests_mon.exit();
@@ -853,7 +888,7 @@ ExternalSeedReaderImpl
 					
 					priority_offsets	 = new int[ (int)getTorrent().getPieceCount()];
 
-					priority_offsets[max_free_reqs_piece] = 10000;
+					priority_offsets[max_free_reqs_piece] = TOP_PIECE_PRIORITY;
 					
 				}else{
 					
@@ -867,7 +902,7 @@ ExternalSeedReaderImpl
 				
 				for (int i=start_piece;i<start_piece+max_contiguous;i++){
 								
-					priority_offsets[i] = 10000 - (i-start_piece);
+					priority_offsets[i] = TOP_PIECE_PRIORITY - (i-start_piece);
 				}
 			}
 		}catch( Throwable e ){
@@ -892,7 +927,7 @@ ExternalSeedReaderImpl
 	
 	protected int
 	selectRequests(
-		List	requests )
+		List<PeerReadRequest>	requests )
 	{
 		long	next_start = -1;
 		
@@ -1003,6 +1038,12 @@ ExternalSeedReaderImpl
    	        	{        		
    	        	}
    	        	
+   	        	public boolean 
+   	        	isCancelled() 
+   	        	{
+   	        		return false;
+   	        	}
+   	        	
    	        	public void
    	        	done()
    	        	{        		
@@ -1034,7 +1075,7 @@ ExternalSeedReaderImpl
 	
 	protected void
 	processRequests(
-		List		requests )
+		List<PeerReadRequest>		requests )
 	{	
 		boolean	ok = false;
 				
@@ -1086,7 +1127,7 @@ ExternalSeedReaderImpl
 	
 	public void
 	addRequests(
-		List	new_requests )
+		List<PeerReadRequest>	new_requests )
 	{
 		try{
 			requests_mon.enter();
@@ -1135,6 +1176,11 @@ ExternalSeedReaderImpl
 				request.cancel();
 			}
 			
+			if ( dangling_requests != null & dangling_requests.contains( request ) && !request.isCancelled()){
+				
+				request.cancel();
+			}
+			
 		}finally{
 			
 			requests_mon.exit();
@@ -1147,16 +1193,25 @@ ExternalSeedReaderImpl
 		try{
 			requests_mon.enter();
 			
-			for (int i=0;i<requests.size();i++){
-				
-				PeerReadRequest	request = (PeerReadRequest)requests.get(i);
-			
+			for ( PeerReadRequest request: requests ){
+							
 				if ( !request.isCancelled()){
 	
 					request.cancel();
 				}
 			}	
 			
+			if ( dangling_requests != null ){
+			
+				for ( PeerReadRequest request: dangling_requests ){
+							
+					if ( !request.isCancelled()){
+	
+						request.cancel();
+					}
+				}
+			}	
+			
 			if ( active_read_request != null ){
 				
 				active_read_request.cancel();
@@ -1181,10 +1236,10 @@ ExternalSeedReaderImpl
 		}	
 	}
 	
-	public List
+	public List<PeerReadRequest>
 	getExpiredRequests()
 	{
-		List	res = null;
+		List<PeerReadRequest>	res = null;
 		
 		try{
 			requests_mon.enter();
@@ -1197,7 +1252,7 @@ ExternalSeedReaderImpl
 					
 					if ( res == null ){
 						
-						res = new ArrayList();
+						res = new ArrayList<PeerReadRequest>();
 					}
 					
 					res.add( request );
@@ -1211,15 +1266,15 @@ ExternalSeedReaderImpl
 		return( res );
 	}
 	
-	public List
+	public List<PeerReadRequest>
 	getRequests()
 	{
-		List	res = null;
+		List<PeerReadRequest>	res = null;
 		
 		try{
 			requests_mon.enter();
 			
-			res = new ArrayList( requests );
+			res = new ArrayList<PeerReadRequest>( requests );
 			
 		}finally{
 			
diff --git a/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderRequest.java b/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderRequest.java
index 0f03960..31841d8 100644
--- a/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderRequest.java
+++ b/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderRequest.java
@@ -35,7 +35,7 @@ ExternalSeedReaderRequest
 {
 	private ExternalSeedReaderImpl	reader;
 	
-	private List			requests;
+	private List<PeerReadRequest>			requests;
 
 	private int		start_piece_number;
 	private int		start_piece_offset;
@@ -49,8 +49,8 @@ ExternalSeedReaderRequest
 	
 	protected 
 	ExternalSeedReaderRequest(
-		ExternalSeedReaderImpl	_reader,
-		List					_requests )
+		ExternalSeedReaderImpl		_reader,
+		List<PeerReadRequest>		_requests )
 	{
 		reader		= _reader;
 		requests	= _requests;
@@ -105,7 +105,23 @@ ExternalSeedReaderRequest
 		
 		return( current_buffer );
 	}
-	        	
+	     
+	public boolean 
+	isCancelled() 
+	{
+		for (int i=0;i<requests.size();i++){
+			
+			PeerReadRequest	req = requests.get(i);
+
+			if ( req.isCancelled()){
+				
+				return( true );
+			}
+		}
+		
+		return( false );
+	}
+	
 	public void
 	done()
 	{
@@ -117,7 +133,7 @@ ExternalSeedReaderRequest
 	{
 		for (int i=0;i<requests.size();i++){
 			
-			PeerReadRequest	req = (PeerReadRequest)requests.get(i);
+			PeerReadRequest	req = requests.get(i);
 
 			if ( !req.isCancelled()){
 				
@@ -131,7 +147,7 @@ ExternalSeedReaderRequest
 	{
 		for (int i=current_request_index;i<requests.size();i++){
 			
-			PeerReadRequest	request = (PeerReadRequest)requests.get(i);
+			PeerReadRequest	request = requests.get(i);
 
 			reader.informFailed( request );
 		}
@@ -179,7 +195,7 @@ ExternalSeedReaderRequest
 		
 		if ( req == null ){
 			
-			req = (PeerReadRequest)requests.get(0);	
+			req = requests.get(0);	
 		}
 		
 		if ( req.isCancelled()){
diff --git a/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderFactoryGetRight.java b/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderFactoryGetRight.java
index 078846b..8d2412f 100644
--- a/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderFactoryGetRight.java
+++ b/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderFactoryGetRight.java
@@ -62,6 +62,13 @@ ExternalSeedReaderFactoryGetRight
   				config.put( "url-list", obj );
   			}
   			
+ 			obj = torrent.getAdditionalProperty( "url-list-params" );
+  			
+  			if ( obj != null ){
+  				
+  				config.put( "url-list-params", obj );
+  			}
+  			
   			return( getSeedReaders( plugin, download, config ));
   			
   		}catch( Throwable e ){
diff --git a/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderGetRight.java b/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderGetRight.java
index df03874..fafc7b4 100644
--- a/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderGetRight.java
+++ b/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderGetRight.java
@@ -28,20 +28,27 @@ import java.net.URLEncoder;
 
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.torrent.TOTorrentFile;
+import org.gudy.azureus2.plugins.peers.PeerManager;
 import org.gudy.azureus2.plugins.torrent.Torrent;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentImpl;
 
+import com.aelitis.azureus.core.peermanager.piecepicker.PiecePicker;
+import com.aelitis.azureus.core.peermanager.piecepicker.PiecePriorityProvider;
 import com.aelitis.azureus.plugins.extseed.ExternalSeedException;
 import com.aelitis.azureus.plugins.extseed.ExternalSeedPlugin;
 import com.aelitis.azureus.plugins.extseed.ExternalSeedReader;
 import com.aelitis.azureus.plugins.extseed.impl.ExternalSeedReaderImpl;
 import com.aelitis.azureus.plugins.extseed.impl.ExternalSeedReaderRequest;
 import com.aelitis.azureus.plugins.extseed.util.ExternalSeedHTTPDownloader;
+import com.aelitis.azureus.plugins.extseed.util.ExternalSeedHTTPDownloaderLinear;
 import com.aelitis.azureus.plugins.extseed.util.ExternalSeedHTTPDownloaderListener;
+import com.aelitis.azureus.plugins.extseed.util.ExternalSeedHTTPDownloaderRange;
 
 public class 
 ExternalSeedReaderGetRight
 	extends ExternalSeedReaderImpl
+	implements PiecePriorityProvider
 {
 	private static final int	TARGET_REQUEST_SIZE_DEFAULT	= 256*1024;
 	
@@ -54,9 +61,12 @@ ExternalSeedReaderGetRight
 	private long[]							downloader_lengths;
 	
 	private int			piece_size;
-
 	private int			piece_group_size;
 		
+	private long[]		piece_priorities;
+	
+	private boolean		linear_download;
+	
 	protected
 	ExternalSeedReaderGetRight(
 		ExternalSeedPlugin 		_plugin,
@@ -70,6 +80,8 @@ ExternalSeedReaderGetRight
 				
 		int target_request_size	= getIntParam( _params, "req_size", TARGET_REQUEST_SIZE_DEFAULT );
 		
+		linear_download	= getBooleanParam( _params, "linear", false );
+
 		url		= _url;
 		
 		ip		= url.getHost();
@@ -95,7 +107,9 @@ ExternalSeedReaderGetRight
 		
 		if ( to_torrent.isSimpleTorrent()){
 			
-			http_downloaders = new ExternalSeedHTTPDownloader[]{ new ExternalSeedHTTPDownloader( url, ua )};
+			http_downloaders = 
+				new ExternalSeedHTTPDownloader[]{ 
+					linear_download?new ExternalSeedHTTPDownloaderLinear( url, ua ):new ExternalSeedHTTPDownloaderRange( url, ua )};
 			
 			downloader_offsets 	= new long[]{ 0 };
 			downloader_lengths	= new long[]{ to_torrent.getSize() };
@@ -137,7 +151,7 @@ ExternalSeedReaderGetRight
 					file_url_str += "/" + URLEncoder.encode( new String( bits[j], "ISO-8859-1" ), "ISO-8859-1" ).replaceAll("\\+", "%20");
 				}
 				
-				http_downloaders[i] = new ExternalSeedHTTPDownloader( new URL( file_url_str), ua );
+				http_downloaders[i] = linear_download?new ExternalSeedHTTPDownloaderLinear( new URL( file_url_str), ua ):new ExternalSeedHTTPDownloaderRange( new URL( file_url_str), ua );
 				
 				downloader_offsets[i]	= offset;
 				downloader_lengths[i]	= length;
@@ -190,6 +204,74 @@ ExternalSeedReaderGetRight
 	}
 		
 	protected void
+	setActiveSupport(
+		PeerManager	peer_manager,
+		boolean		active )
+	{
+		if ( linear_download ){
+			
+				// force overall download order to be from end of file to start (for BT peers)
+			
+			if ( peer_manager != null ){
+				
+				PiecePicker picker = PluginCoreUtils.unwrap( peer_manager ).getPiecePicker();
+	
+				if ( active ){
+					
+					piece_priorities = new long[peer_manager.getPieces().length];
+					
+					for ( int i=0;i<piece_priorities.length;i++){
+						
+						piece_priorities[i] = 10*1000 +  i;
+					}
+					
+					picker.addPriorityProvider( this );
+					
+				}else{
+					
+					piece_priorities = null;
+					
+					picker.removePriorityProvider( this );
+				}
+			}
+			
+			if ( !active ){
+				
+				for ( ExternalSeedHTTPDownloader d: http_downloaders ){
+					
+					d.deactivate();
+				}
+			}
+		}
+	}
+	
+	public long[]
+	updatePriorities(
+		PiecePicker		picker )
+	{
+		return( piece_priorities );
+	}
+	
+	public void
+	calculatePriorityOffsets(
+		PeerManager		peer_manager,
+		int[]			base_priorities )
+	{
+		if ( linear_download ){
+			
+				// force us linear from front of file to end
+			
+			for (int i=0;i<base_priorities.length;i++){
+				
+				base_priorities[i] = TOP_PIECE_PRIORITY + base_priorities.length - ( i + 1 );
+			}
+		}else{
+			
+			super.calculatePriorityOffsets( peer_manager, base_priorities );
+		}
+	}
+	
+	protected void
 	readData(
 		ExternalSeedReaderRequest	request )
 	
@@ -346,6 +428,12 @@ ExternalSeedReaderGetRight
 			        		listener.reportBytesRead( num );
 			        	}
 			        	
+			        	public boolean 
+			        	isCancelled() 
+			        	{
+			        		return( listener.isCancelled());
+			        	}
+			        	
 			        	public void
 			        	done()
 			        	{
diff --git a/com/aelitis/azureus/plugins/extseed/impl/webseed/ExternalSeedReaderWebSeed.java b/com/aelitis/azureus/plugins/extseed/impl/webseed/ExternalSeedReaderWebSeed.java
index 1436bdb..4c39c35 100644
--- a/com/aelitis/azureus/plugins/extseed/impl/webseed/ExternalSeedReaderWebSeed.java
+++ b/com/aelitis/azureus/plugins/extseed/impl/webseed/ExternalSeedReaderWebSeed.java
@@ -36,6 +36,7 @@ import com.aelitis.azureus.plugins.extseed.ExternalSeedReader;
 import com.aelitis.azureus.plugins.extseed.impl.ExternalSeedReaderImpl;
 import com.aelitis.azureus.plugins.extseed.util.ExternalSeedHTTPDownloader;
 import com.aelitis.azureus.plugins.extseed.util.ExternalSeedHTTPDownloaderListener;
+import com.aelitis.azureus.plugins.extseed.util.ExternalSeedHTTPDownloaderRange;
 
 public class 
 ExternalSeedReaderWebSeed
@@ -141,7 +142,7 @@ ExternalSeedReaderWebSeed
 		ExternalSeedHTTPDownloader	http_downloader = null;
 		
 		try{
-			http_downloader = new ExternalSeedHTTPDownloader( new URL( str ), getUserAgent());
+			http_downloader = new ExternalSeedHTTPDownloaderRange( new URL( str ), getUserAgent());
 
 				// unfortunately using HttpURLConnection it isn't possible to read the 503 response as per
 				// protocol - however, for az http web seeds we don't uses 503 anyway so we cna use URLCon. The
diff --git a/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloader.java b/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloader.java
index d175089..9ff5042 100644
--- a/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloader.java
+++ b/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloader.java
@@ -22,62 +22,19 @@
 
 package com.aelitis.azureus.plugins.extseed.util;
 
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.InetSocketAddress;
-import java.net.PasswordAuthentication;
-import java.net.Socket;
-import java.net.URL;
-import java.util.StringTokenizer;
 
-import org.gudy.azureus2.core3.security.SEPasswordListener;
-import org.gudy.azureus2.core3.security.SESecurityManager;
-import org.gudy.azureus2.core3.util.Debug;
-
-import com.aelitis.azureus.core.util.Java15Utils;
 import com.aelitis.azureus.plugins.extseed.ExternalSeedException;
 
-public class 
+public interface 
 ExternalSeedHTTPDownloader 
-	implements SEPasswordListener
 {
-	public static final String	NL = "\r\n";
-	
-
-	private URL			url;
-	private String		user_agent;
-	
-	private int			last_response;
-	private int			last_response_retry_after_secs;
-    	
-	public
-	ExternalSeedHTTPDownloader(
-		URL		_url,
-		String	_user_agent )
-	{
-		url			= _url;
-		user_agent	= _user_agent;
-	}
-	
-	public URL
-	getURL()
-	{
-		return( url );
-	}
-	
 	public void
 	download(
 		int									length,
 		ExternalSeedHTTPDownloaderListener	listener,
 		boolean								con_fail_is_perm_fail )
 	
-		throws ExternalSeedException
-	{
-		download( new String[0], new String[0], length, listener, con_fail_is_perm_fail );
-	}
+		throws ExternalSeedException;
 	
 	public void
 	downloadRange(
@@ -86,541 +43,22 @@ ExternalSeedHTTPDownloader
 		ExternalSeedHTTPDownloaderListener	listener,
 		boolean								con_fail_is_perm_fail )
 	
-		throws ExternalSeedException
-	{
-		download( 	new String[]{ "Range" }, new String[]{ "bytes=" + offset + "-" + (offset+length-1)},
-					length,
-					listener,
-					con_fail_is_perm_fail );
-	}
-	
-	public void
-	download(
-		String[]							prop_names,
-		String[]							prop_values,
-		int									length,
-		ExternalSeedHTTPDownloaderListener	listener,
-		boolean								con_fail_is_perm_fail )
-	
-		throws ExternalSeedException
-	{
-		boolean	connected = false;
-		
-		InputStream	is	= null;
-				
-		String	outcome = "";
-		
-		try{
-			SESecurityManager.setThreadPasswordHandler( this );
-			
-			// System.out.println( "Connecting to " + url + ": " + Thread.currentThread().getId());
-
-			HttpURLConnection	connection = (HttpURLConnection)url.openConnection();
-			
-			connection.setRequestProperty( "Connection", "Keep-Alive" );
-			connection.setRequestProperty( "User-Agent", user_agent );
-			
-			for (int i=0;i<prop_names.length;i++){
-				
-				connection.setRequestProperty( prop_names[i], prop_values[i] );
-			}
-			
-			int	time_remaining	= listener.getPermittedTime();
-			
-			if ( time_remaining > 0 ){
-				
-				Java15Utils.setConnectTimeout( connection, time_remaining );
-			}
-						
-			connection.connect();
-			
-			time_remaining	= listener.getPermittedTime();
-								
-			if ( time_remaining < 0 ){
-				
-				throw( new IOException( "Timeout during connect" ));
-			}
-			
-			Java15Utils.setReadTimeout( connection, time_remaining );
-					
-			connected	= true;
-			
-			int	response = connection.getResponseCode();
-
-			last_response	= response;
-			
-			last_response_retry_after_secs	= -1;
-			
-            if ( response == 503 ){
-                           
-                	// webseed support for temp unavail - read the retry_after
-            	
-            	long retry_after_date = new Long(connection.getHeaderFieldDate("Retry-After", -1L)).longValue();
-            	
-                if ( retry_after_date <= -1 ){
-                	
-                	last_response_retry_after_secs = connection.getHeaderFieldInt("Retry-After", -1);
-                    
-                }else{
-                	
-                	last_response_retry_after_secs = (int)((retry_after_date - System.currentTimeMillis())/1000);
-                	
-                	if ( last_response_retry_after_secs < 0 ){
-                		
-                		last_response_retry_after_secs = -1;
-                	}
-                }
-            }
-            
-			is = connection.getInputStream();
-			
-			if ( 	response == HttpURLConnection.HTTP_ACCEPTED || 
-					response == HttpURLConnection.HTTP_OK ||
-					response == HttpURLConnection.HTTP_PARTIAL ){
-								
-				int	pos = 0;
-				
-				byte[]	buffer 		= null;
-				int		buffer_pos	= 0;
-				int		buffer_len	= 0;
-
-				while( pos < length ){
-					
-					if ( buffer == null ){
-						
-						buffer 		= listener.getBuffer();						
-						buffer_pos	= listener.getBufferPosition();
-						buffer_len	= listener.getBufferLength();
-					}
-
-					listener.setBufferPosition( buffer_pos );
-					
-					int	to_read = buffer_len - buffer_pos;
-					
-					int	permitted = listener.getPermittedBytes();
-					
-					if ( permitted < to_read ){
-						
-						to_read	= permitted;
-					}
-					
-					int	len = is.read( buffer, buffer_pos, to_read );
-					
-					if ( len < 0 ){
-						
-						break;
-					}
-					
-					listener.reportBytesRead( len );
-					
-					pos	+= len;
-					
-					buffer_pos	+= len;
-					
-					if ( buffer_pos == buffer_len ){
-						
-						listener.done();
-						
-						buffer		= null;
-						buffer_pos	= 0;
-					}
-				}
-				
-				if ( pos != length ){
-					
-					String	log_str;
-					
-					if ( buffer == null ){
-						
-						log_str = "No buffer assigned";
-						
-					}else{
-						
-						log_str =  new String( buffer, 0, length );
-						
-						if ( log_str.length() > 64 ){
-							
-							log_str = log_str.substring( 0, 64 );
-						}
-					}
-					
-					outcome = "Connection failed: data too short - " + length + "/" + pos + " [" + log_str + "]";
-					
-					throw( new ExternalSeedException( outcome ));
-				}
-				
-				outcome = "read " + pos + " bytes";
-				
-				// System.out.println( "download length: " + pos );
-				
-			}else{
-				
-				outcome = "Connection failed: " + connection.getResponseMessage();
-				
-				ExternalSeedException	error = new ExternalSeedException( outcome );
-				
-				error.setPermanentFailure( true );
-				
-				throw( error );
-			}
-		}catch( IOException e ){
-			
-			if ( con_fail_is_perm_fail && !connected ){
-				
-				outcome = "Connection failed: " + e.getMessage();
-				
-				ExternalSeedException	error = new ExternalSeedException( outcome );
-				
-				error.setPermanentFailure( true );
-				
-				throw( error );
-
-			}else{
-				
-				outcome =  "Connection failed: " + Debug.getNestedExceptionMessage( e );
-                
-                if ( last_response_retry_after_secs >= 0){
-                	
-                    outcome += ", Retry-After: " + last_response_retry_after_secs + " seconds";
-                }
-				                
-				ExternalSeedException excep = new ExternalSeedException( outcome, e );
-				
-				if ( e instanceof FileNotFoundException ){
-					
-					excep.setPermanentFailure( true );
-				}
-				
-				throw( excep );
-			}
-		}catch( Throwable e ){
-			
-			if ( e instanceof ExternalSeedException ){
-				
-				throw((ExternalSeedException)e);
-			}
-			
-			outcome = "Connection failed: " + Debug.getNestedExceptionMessage( e );
-			
-			throw( new ExternalSeedException("Connection failed", e ));
-			
-		}finally{
-			
-			SESecurityManager.unsetThreadPasswordHandler();
-
-			// System.out.println( "Done to " + url + ": " + Thread.currentThread().getId() + ", outcome=" + outcome );
-
-			if ( is != null ){
-				
-				try{
-					is.close();
-					
-				}catch( Throwable e ){
-					
-				}
-			}
-		}
-	}
-	
-	public void
-	downloadSocket(
-		int									length,
-		ExternalSeedHTTPDownloaderListener	listener,
-		boolean								con_fail_is_perm_fail )
-	        	
-	    throws ExternalSeedException
-	{
-		downloadSocket( new String[0], new String[0], length, listener, con_fail_is_perm_fail );
-	}
+		throws ExternalSeedException;
 	
 	public void
 	downloadSocket(
-		String[]							prop_names,
-		String[]							prop_values,
 		int									length,
 		ExternalSeedHTTPDownloaderListener	listener,
 		boolean								con_fail_is_perm_fail )
-	
-		throws ExternalSeedException
-	{
-		Socket	socket	= null;
-		
-		boolean	connected = false;
-		
-		try{				
-			String	output_header = 
-				"GET " + url.getPath() + "?" + url.getQuery() + " HTTP/1.1" + NL +
-				"Host: " + url.getHost() + (url.getPort()==-1?"":( ":" + url.getPort())) + NL +
-				"Accept: */*" + NL +
-				"Connection: Close" + NL +	// if we want to support keep-alive we'll need to implement a socket cache etc.
-				"User-Agent: " + user_agent + NL;
-		
-			for (int i=0;i<prop_names.length;i++){
-				
-				output_header += prop_names[i] + ":" + prop_values[i] + NL;
-			}
-			
-			output_header += NL;
-			
-			int	time_remaining	= listener.getPermittedTime();
-			
-			if ( time_remaining > 0 ){
-				
-				socket = new Socket();
-				
-				socket.connect( new InetSocketAddress( url.getHost(), url.getPort()==-1?url.getDefaultPort():url.getPort()), time_remaining );
-				
-			}else{
-		
-				socket = new Socket(  url.getHost(), url.getPort()==-1?url.getDefaultPort():url.getPort());
-			}
-			
-			connected	= true;
-			
-			time_remaining	= listener.getPermittedTime();
-
-			if ( time_remaining < 0 ){
-					
-				throw( new IOException( "Timeout during connect" ));
-				
-			}else if ( time_remaining > 0 ){
-				
-				socket.setSoTimeout( time_remaining );
-			}
-			
-			OutputStream	os = socket.getOutputStream();
-			
-			os.write( output_header.getBytes( "ISO-8859-1" ));
-			
-			os.flush();
-			
-			InputStream is = socket.getInputStream();
-			
-			try{
-				String	input_header = "";
-				
-				while( true ){
-					
-					byte[]	buffer = new byte[1];
-					
-					int	len = is.read( buffer );
-					
-					if ( len < 0 ){
-						
-						throw( new IOException( "input too short reading header" ));
-					}
-					
-					input_header	+= (char)buffer[0];
-					
-					if ( input_header.endsWith(NL+NL)){
-					
-						break;
-					}
-				}
-								
-				// HTTP/1.1 403 Forbidden
-				
-				int	line_end = input_header.indexOf(NL);
-				
-				if ( line_end == -1 ){
-					
-					throw( new IOException( "header too short" ));
-				}
-				
-				String	first_line = input_header.substring(0,line_end);
-				
-				StringTokenizer	tok = new StringTokenizer(first_line, " " );
-				
-				tok.nextToken();
-				
-				int	response = Integer.parseInt( tok.nextToken());
-				
-				last_response	= response;
-				
-				last_response_retry_after_secs	= -1;
-				
-				String	response_str	= tok.nextToken();				
-				
-				if ( 	response == HttpURLConnection.HTTP_ACCEPTED || 
-						response == HttpURLConnection.HTTP_OK ||
-						response == HttpURLConnection.HTTP_PARTIAL ){
-					
-					byte[]	buffer 		= null;
-					int		buffer_pos	= 0;
-					int		buffer_len	= 0;
-					
-					int	pos = 0;
-					
-					while( pos < length ){
-						
-						if ( buffer == null ){
-							
-							buffer 		= listener.getBuffer();							
-							buffer_pos	= listener.getBufferPosition();
-							buffer_len	= listener.getBufferLength();
-						}
-						
-						int	to_read = buffer_len - buffer_pos;
-						
-						int	permitted = listener.getPermittedBytes();
-						
-						if ( permitted < to_read ){
-							
-							to_read	= permitted;
-						}
-						
-						int	len = is.read( buffer, buffer_pos, to_read );
-						
-						if ( len < 0 ){
-							
-							break;
-						}
-						
-						listener.reportBytesRead( len );
-						
-						pos	+= len;
-						
-						buffer_pos	+= len;
-						
-						if ( buffer_pos == buffer_len ){
-							
-							listener.done();
-							
-							buffer		= null;
-							buffer_pos	= 0;
-						}
-					}
-					
-					if ( pos != length ){
-						
-						String	log_str;
-						
-						if ( buffer == null ){
-							
-							log_str = "No buffer assigned";
-							
-						}else{
-							
-							log_str =  new String( buffer, 0, buffer_pos>64?64:buffer_pos );
-						}
-						
-						throw( new ExternalSeedException("Connection failed: data too short - " + length + "/" + pos + " [last=" + log_str + "]" ));
-					}
-					
-					// System.out.println( "download length: " + pos );
-										
-				}else if ( 	response == 503 ){
-					
-						// webseed support for temp unavail - read the data
-					
-					String	data_str = "";
-					
-					while( true ){
-						
-						byte[]	buffer = new byte[1];
-						
-						int	len = is.read( buffer );
-						
-						if ( len < 0 ){
-							
-							break;
-						}
-						
-						data_str += (char)buffer[0];
-					}
-					
-					last_response_retry_after_secs = Integer.parseInt( data_str );
-				
-						// this gets trapped below and turned into an appropriate ExternalSeedException
-					
-					throw( new IOException( "Server overloaded" ));
-					
-				}else{
-					
-					ExternalSeedException	error = new ExternalSeedException("Connection failed: " + response_str );
-					
-					error.setPermanentFailure( true );
-					
-					throw( error );
-				}
-			}finally{
-				
-				is.close();
-			}
-			
-		}catch( IOException e ){
-			
-			if ( con_fail_is_perm_fail && !connected ){
-				
-				ExternalSeedException	error = new ExternalSeedException("Connection failed: " + e.getMessage());
-				
-				error.setPermanentFailure( true );
-				
-				throw( error );
-
-			}else{
-				
-				String outcome =  "Connection failed: " + Debug.getNestedExceptionMessage( e );
-
-				if ( last_response_retry_after_secs >= 0 ){
-	                	
-					outcome += ", Retry-After: " + last_response_retry_after_secs + " seconds";
-	            }
-
-				throw( new ExternalSeedException( outcome, e ));
-			}
-		}catch( Throwable e ){
-						
-			if ( e instanceof ExternalSeedException ){
-				
-				throw((ExternalSeedException)e);
-			}
-			
-			throw( new ExternalSeedException("Connection failed", e ));
-			
-		}finally{
-			
-			if ( socket != null ){
-				
-				try{
-					socket.close();
-					
-				}catch( Throwable e ){
-				}
-			}
-		}
-	}
-	
-	public PasswordAuthentication
-	getAuthentication(
-		String		realm,
-		URL			tracker )
-	{
-		return( null );
-	}
-	
-	public void
-	setAuthenticationOutcome(
-		String		realm,
-		URL			tracker,
-		boolean		success )
-	{
-	}
-	
-	public void
-	clearPasswords()
-	{
-	}
+		        	
+	    throws ExternalSeedException;
 	
 	public int
-	getLastResponse()
-	{
-		return( last_response );
-	}
+	getLastResponse();
 	
 	public int
-	getLast503RetrySecs()
-	{
-		return( last_response_retry_after_secs );
-	}
+	getLast503RetrySecs();
+	
+	public void
+	deactivate();
 }
diff --git a/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderLinear.java b/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderLinear.java
new file mode 100644
index 0000000..52fa601
--- /dev/null
+++ b/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderLinear.java
@@ -0,0 +1,651 @@
+/*
+ * Created on Oct 21, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package com.aelitis.azureus.plugins.extseed.util;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.net.HttpURLConnection;
+import java.net.PasswordAuthentication;
+import java.net.URL;
+import java.util.*;
+
+import org.gudy.azureus2.core3.security.SEPasswordListener;
+import org.gudy.azureus2.core3.security.SESecurityManager;
+import org.gudy.azureus2.core3.util.AESemaphore;
+import org.gudy.azureus2.core3.util.AETemporaryFileHandler;
+import org.gudy.azureus2.core3.util.AEThread2;
+import org.gudy.azureus2.core3.util.Debug;
+
+import com.aelitis.azureus.core.util.Java15Utils;
+import com.aelitis.azureus.plugins.extseed.ExternalSeedException;
+
+public class 
+ExternalSeedHTTPDownloaderLinear 
+	implements ExternalSeedHTTPDownloader
+{
+	private URL			original_url;
+	private String		user_agent;
+	
+	private int			last_response;
+	private int			last_response_retry_after_secs;
+
+	private Downloader	downloader;
+	
+	
+	
+	public
+	ExternalSeedHTTPDownloaderLinear(
+		URL		_url,
+		String	_user_agent )
+	{
+		original_url	= _url;
+		user_agent		= _user_agent;
+	}
+	
+	
+	public void
+	downloadRange(
+		long								offset,
+		int									length,
+		ExternalSeedHTTPDownloaderListener	listener,
+		boolean								con_fail_is_perm_fail )
+	
+		throws ExternalSeedException
+	{
+		Request request;
+		
+		synchronized( this ){
+			
+			if ( downloader == null ){
+				
+				downloader = new Downloader( listener, con_fail_is_perm_fail );
+			}
+			
+			request = downloader.addRequest( offset, length, listener );
+		}
+		
+		while( true ){
+			
+			if ( request.waitFor(1000)){
+				
+				return;
+			}
+			
+			if ( listener.isCancelled()){
+				
+				throw( new ExternalSeedException( "request cancelled" ));
+			}
+		}
+	}
+	
+	public void
+	deactivate()
+	{
+		Downloader	to_destroy = null;
+		
+		synchronized( this ){
+			
+			if ( downloader != null ){
+				
+				to_destroy = downloader;
+								
+				downloader = null;
+			}
+		}
+		
+		if ( to_destroy != null ){
+			
+			to_destroy.destroy( new ExternalSeedException( "deactivated" ));
+		}
+	}
+	
+	protected void
+	destoyed(
+		Downloader		dead )
+	{
+		synchronized( this ){
+			
+			if ( downloader == dead ){
+
+				downloader = null;
+			}
+		}
+	}
+	
+	public void
+	download(
+		int									length,
+		ExternalSeedHTTPDownloaderListener	listener,
+		boolean								con_fail_is_perm_fail )
+	
+		throws ExternalSeedException
+	{
+		throw( new ExternalSeedException( "not supported" ));
+	}
+
+	public void
+	downloadSocket(
+		int									length,
+		ExternalSeedHTTPDownloaderListener	listener,
+		boolean								con_fail_is_perm_fail )
+		        	
+	    throws ExternalSeedException
+	{
+		throw( new ExternalSeedException( "not supported" ));
+	}
+	
+	public int
+	getLastResponse()
+	{
+		return( last_response );
+	}
+	
+	public int
+	getLast503RetrySecs()
+	{
+		return( last_response_retry_after_secs );
+	}
+	
+	protected class
+	Downloader
+		implements SEPasswordListener
+	{
+		private ExternalSeedHTTPDownloaderListener	listener;
+		private boolean								con_fail_is_perm_fail;
+	
+		private volatile boolean	destroyed;
+		
+		private List<Request>		requests = new ArrayList<Request>();
+			
+		private RandomAccessFile	raf				= null;
+		private File				scratch_file	= null;
+
+		protected
+		Downloader(
+			ExternalSeedHTTPDownloaderListener	_listener,
+			boolean								_con_fail_is_perm_fail )
+		{
+			listener				= _listener;
+			con_fail_is_perm_fail	= _con_fail_is_perm_fail;
+						
+			new AEThread2( "ES:downloader", true )
+			{
+				public void
+				run()
+				{
+					download();
+				}
+			}.start();
+		}
+		
+		protected void
+		download()
+		{
+			boolean	connected 	= false;
+			String	outcome		= "";
+			
+			try{
+				InputStream			is				= null;
+				
+				try{
+					SESecurityManager.setThreadPasswordHandler( this );
+					
+					synchronized( this ){
+					
+						if ( destroyed ){
+							
+							return;
+						}
+						
+						scratch_file = AETemporaryFileHandler.createTempFile();
+
+						raf = new RandomAccessFile( scratch_file, "rw" );
+					}
+										
+					// System.out.println( "Connecting to " + url + ": " + Thread.currentThread().getId());
+	
+					HttpURLConnection	connection;
+					int					response;
+					
+					connection = (HttpURLConnection)original_url.openConnection();
+						
+					connection.setRequestProperty( "Connection", "Keep-Alive" );
+					connection.setRequestProperty( "User-Agent", user_agent );
+						
+					int	time_remaining	= listener.getPermittedTime();
+					
+					if ( time_remaining > 0 ){
+						
+						Java15Utils.setConnectTimeout( connection, time_remaining );
+					}
+								
+					connection.connect();
+				
+					time_remaining	= listener.getPermittedTime();
+										
+					if ( time_remaining < 0 ){
+						
+						throw( new IOException( "Timeout during connect" ));
+					}
+					
+					Java15Utils.setReadTimeout( connection, time_remaining );
+							
+					connected	= true;
+					
+					response = connection.getResponseCode();
+					
+					last_response	= response;
+					
+					last_response_retry_after_secs	= -1;
+					
+		            if ( response == 503 ){
+		                           
+		                	// webseed support for temp unavail - read the retry_after
+		            	
+		            	long retry_after_date = new Long(connection.getHeaderFieldDate("Retry-After", -1L)).longValue();
+		            	
+		                if ( retry_after_date <= -1 ){
+		                	
+		                	last_response_retry_after_secs = connection.getHeaderFieldInt("Retry-After", -1);
+		                    
+		                }else{
+		                	
+		                	last_response_retry_after_secs = (int)((retry_after_date - System.currentTimeMillis())/1000);
+		                	
+		                	if ( last_response_retry_after_secs < 0 ){
+		                		
+		                		last_response_retry_after_secs = -1;
+		                	}
+		                }
+		            }
+		            
+					is = connection.getInputStream();
+					
+					if ( 	response == HttpURLConnection.HTTP_ACCEPTED || 
+							response == HttpURLConnection.HTTP_OK ||
+							response == HttpURLConnection.HTTP_PARTIAL ){
+						
+						byte[]	buffer = new byte[64*1024];
+						
+						int	requests_outstanding = 1;	// should be one at least
+						
+						while( !destroyed ){
+													
+							int	permitted = listener.getPermittedBytes();
+							
+								// idle if no reqs
+							
+							if ( requests_outstanding == 0 || permitted < 1 ){
+								
+								permitted = 1;
+								
+								Thread.sleep( 100 );
+							}
+							
+							int	len = is.read( buffer, 0, Math.min( permitted, buffer.length ));
+							
+							if ( len <= 0 ){
+								
+								break;
+							}
+							
+							synchronized( this ){
+							
+								try{
+									raf.write( buffer, 0, len );
+									
+								}catch( Throwable e ){
+									
+										// assume out of space of something permanent, abandon
+									
+									outcome = "Write failed: " + e.getMessage();
+									
+									ExternalSeedException	error = new ExternalSeedException( outcome, e );
+									
+									error.setPermanentFailure( true );
+									
+									throw( error );
+								}
+							}
+							
+							listener.reportBytesRead( len );
+							
+							requests_outstanding = checkRequests();
+						}
+						
+						checkRequests();
+						
+					}else{
+						
+						outcome = "Connection failed: " + connection.getResponseMessage();
+						
+						ExternalSeedException	error = new ExternalSeedException( outcome );
+						
+						error.setPermanentFailure( true );
+						
+						throw( error );
+					}
+				}catch( IOException e ){
+					
+					if ( con_fail_is_perm_fail && !connected ){
+						
+						outcome = "Connection failed: " + e.getMessage();
+						
+						ExternalSeedException	error = new ExternalSeedException( outcome );
+						
+						error.setPermanentFailure( true );
+						
+						throw( error );
+	
+					}else{
+						
+						outcome =  "Connection failed: " + Debug.getNestedExceptionMessage( e );
+		                
+		                if ( last_response_retry_after_secs >= 0){
+		                	
+		                    outcome += ", Retry-After: " + last_response_retry_after_secs + " seconds";
+		                }
+						                
+						ExternalSeedException excep = new ExternalSeedException( outcome, e );
+						
+						if ( e instanceof FileNotFoundException ){
+							
+							excep.setPermanentFailure( true );
+						}
+						
+						throw( excep );
+					}
+				}catch( ExternalSeedException e ){
+
+					throw( e );
+					
+				}catch( Throwable e ){
+					
+					if ( e instanceof ExternalSeedException ){
+						
+						throw((ExternalSeedException)e);
+					}
+					
+					outcome = "Connection failed: " + Debug.getNestedExceptionMessage( e );
+					
+					throw( new ExternalSeedException("Connection failed", e ));
+					
+				}finally{
+					
+					SESecurityManager.unsetThreadPasswordHandler();
+	
+					// System.out.println( "Done to " + url + ": " + Thread.currentThread().getId() + ", outcome=" + outcome );
+	
+					if ( is != null ){
+						
+						try{
+							is.close();
+							
+						}catch( Throwable e ){			
+						}
+					}
+				}
+			}catch( ExternalSeedException e ){
+				
+				if ( !connected && con_fail_is_perm_fail ){
+					
+					e.setPermanentFailure( true );
+				}
+				
+				destroy( e );
+			}
+			
+				// on successful completion we kill the read thread but leave things 'running' so we continue to service
+				// requests. We will be de-activated when no longer required
+		}
+		
+		protected Request
+		addRequest(
+			long								offset,
+			int									length,
+			ExternalSeedHTTPDownloaderListener	listener )
+		
+			throws ExternalSeedException
+		{
+			Request request;
+			
+			synchronized( this ){
+				
+				if ( destroyed ){
+					
+					throw( new ExternalSeedException( "downloader destroyed" ));
+				}
+			
+				request = new Request( offset, length, listener );
+				
+				requests.add( request );
+			}
+			
+			checkRequests();
+			
+			return( request );
+		}
+		
+		protected int
+		checkRequests()
+		{				
+			try{
+				synchronized( this ){
+
+					if ( raf == null ){
+						
+							// not yet initialised
+					
+						return( requests.size());
+					}
+
+					long pos = raf.getFilePointer();
+					
+					Iterator<Request> it = requests.iterator();
+					
+					while( it.hasNext()){
+						
+						Request request = it.next();
+						
+						long	end = request.getOffset() + request.getLength();
+						
+						if ( pos >= end ){
+							
+							ExternalSeedHTTPDownloaderListener listener = request.getListener();
+							
+							try{
+								raf.seek( request.getOffset());
+								
+								int	total = 0;
+								
+								while( total < request.getLength()){
+									
+									byte[]	buffer 		= listener.getBuffer();
+									int		buffer_len	= listener.getBufferLength();
+									
+									raf.read( buffer, 0, buffer_len );
+									
+									total += buffer_len;
+									
+									listener.done();
+								}
+							}finally{
+								
+								raf.seek( pos );
+							}
+														
+							request.complete();
+							
+							it.remove();
+						}
+					}
+					
+					return( requests.size());
+				}		
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+				
+				destroy( new ExternalSeedException( "read failed", e ));
+				
+				return( 0 );
+			}
+		}
+		
+		protected void
+		destroy(
+			ExternalSeedException	error )
+		{
+			synchronized( this ){
+				
+				if ( destroyed ){
+					
+					return;
+				}
+			
+				destroyed	= true;
+				
+				if ( raf != null ){
+					
+					try{
+						raf.close();
+			
+					}catch( Throwable e ){
+					}
+				}
+				
+				if ( scratch_file != null ){
+					
+					scratch_file.delete();
+				}
+				
+				for ( Request r: requests ){
+					
+					r.destroy( error );
+				}
+				
+				requests.clear();
+			}
+			
+			ExternalSeedHTTPDownloaderLinear.this.destoyed( this );
+		}
+		
+		public PasswordAuthentication
+		getAuthentication(
+			String		realm,
+			URL			tracker )
+		{
+			return( null );
+		}
+		
+		public void
+		setAuthenticationOutcome(
+			String		realm,
+			URL			tracker,
+			boolean		success )
+		{
+		}
+		
+		public void
+		clearPasswords()
+		{
+		}
+	}
+	
+	protected class
+	Request
+	{
+		private long									offset;
+		private int										length;
+		private ExternalSeedHTTPDownloaderListener		listener;
+		
+		private AESemaphore	sem = new AESemaphore( "ES:wait" );
+		
+		private volatile ExternalSeedException	exception;
+		
+		protected
+		Request(
+			long									_offset,
+			int										_length,
+			ExternalSeedHTTPDownloaderListener		_listener )
+		{
+			offset		= _offset;
+			length		= _length;
+			listener	= _listener;
+		}
+		
+		protected long
+		getOffset()
+		{
+			return( offset );
+		}
+		
+		protected int
+		getLength()
+		{
+			return( length );
+		}
+		
+		protected ExternalSeedHTTPDownloaderListener
+		getListener()
+		{
+			return( listener );
+		}
+		
+		protected void
+		complete()
+		{
+			sem.release();
+		}
+		
+		protected void
+		destroy(
+			ExternalSeedException	e )
+		{
+			exception = e;
+			
+			sem.release();
+		}
+				
+		public boolean
+		waitFor(
+			int	timeout )
+		
+			throws ExternalSeedException
+		{			
+			if ( !sem.reserve( timeout )){
+				
+				return( false );
+			}
+			
+			if ( exception != null ){
+				
+				throw( exception );
+			}
+			
+			return( true );
+		}		
+	}
+}
diff --git a/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderListener.java b/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderListener.java
index ae708e9..0724259 100644
--- a/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderListener.java
+++ b/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderListener.java
@@ -54,6 +54,9 @@ ExternalSeedHTTPDownloaderListener
 	reportBytesRead(
 		int		num );
 	
+	public boolean
+	isCancelled();
+	
 	public void
 	done();
 }
diff --git a/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderRange.java b/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderRange.java
new file mode 100644
index 0000000..b333cc6
--- /dev/null
+++ b/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderRange.java
@@ -0,0 +1,759 @@
+/*
+ * Created on 16-Dec-2005
+ * Created by Paul Gardner
+ * Copyright (C) 2005, 2006 Aelitis, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * 
+ * AELITIS, SAS au capital de 46,603.30 euros
+ * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
+ *
+ */
+
+package com.aelitis.azureus.plugins.extseed.util;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.Socket;
+import java.net.URL;
+import java.util.StringTokenizer;
+
+import org.gudy.azureus2.core3.security.SEPasswordListener;
+import org.gudy.azureus2.core3.security.SESecurityManager;
+import org.gudy.azureus2.core3.util.Debug;
+
+import com.aelitis.azureus.core.util.Java15Utils;
+import com.aelitis.azureus.plugins.extseed.ExternalSeedException;
+
+public class 
+ExternalSeedHTTPDownloaderRange 
+	implements ExternalSeedHTTPDownloader, SEPasswordListener
+{
+	public static final String	NL = "\r\n";
+	
+
+	private URL			original_url;
+	private String		user_agent;
+	
+	private URL			redirected_url;
+	private int			consec_redirect_fails;
+	
+	private int			last_response;
+	private int			last_response_retry_after_secs;
+    	
+	public
+	ExternalSeedHTTPDownloaderRange(
+		URL		_url,
+		String	_user_agent )
+	{
+		original_url	= _url;
+		user_agent		= _user_agent;
+	}
+	
+	public URL
+	getURL()
+	{
+		return( original_url );
+	}
+	
+	public void
+	download(
+		int									length,
+		ExternalSeedHTTPDownloaderListener	listener,
+		boolean								con_fail_is_perm_fail )
+	
+		throws ExternalSeedException
+	{
+		download( new String[0], new String[0], length, listener, con_fail_is_perm_fail );
+	}
+	
+	public void
+	downloadRange(
+		long								offset,
+		int									length,
+		ExternalSeedHTTPDownloaderListener	listener,
+		boolean								con_fail_is_perm_fail )
+	
+		throws ExternalSeedException
+	{
+		download( 	new String[]{ "Range" }, new String[]{ "bytes=" + offset + "-" + (offset+length-1)},
+					length,
+					listener,
+					con_fail_is_perm_fail );
+	}
+	
+	public void
+	download(
+		String[]							prop_names,
+		String[]							prop_values,
+		int									length,
+		ExternalSeedHTTPDownloaderListener	listener,
+		boolean								con_fail_is_perm_fail )
+	
+		throws ExternalSeedException
+	{
+		boolean	connected = false;
+		
+		InputStream	is	= null;
+				
+		String	outcome = "";
+		
+		try{
+			SESecurityManager.setThreadPasswordHandler( this );
+			
+			// System.out.println( "Connecting to " + url + ": " + Thread.currentThread().getId());
+
+			HttpURLConnection	connection;
+			int					response;
+			
+			while( true ){
+				
+				URL	target = redirected_url==null?original_url:redirected_url;
+				
+				connection = (HttpURLConnection)target.openConnection();
+				
+				connection.setRequestProperty( "Connection", "Keep-Alive" );
+				connection.setRequestProperty( "User-Agent", user_agent );
+				
+				for (int i=0;i<prop_names.length;i++){
+					
+					connection.setRequestProperty( prop_names[i], prop_values[i] );
+				}
+				
+				int	time_remaining	= listener.getPermittedTime();
+				
+				if ( time_remaining > 0 ){
+					
+					Java15Utils.setConnectTimeout( connection, time_remaining );
+				}
+							
+				connection.connect();
+			
+				time_remaining	= listener.getPermittedTime();
+									
+				if ( time_remaining < 0 ){
+					
+					throw( new IOException( "Timeout during connect" ));
+				}
+				
+				Java15Utils.setReadTimeout( connection, time_remaining );
+						
+				connected	= true;
+				
+				response = connection.getResponseCode();
+
+				if (	response == HttpURLConnection.HTTP_ACCEPTED || 
+						response == HttpURLConnection.HTTP_OK ||
+						response == HttpURLConnection.HTTP_PARTIAL ){
+					
+					if ( redirected_url != null ){
+						
+						consec_redirect_fails = 0;
+					}
+					
+					break;
+				}
+				
+				if ( redirected_url == null ){
+					
+					break;
+				}
+				
+					// try again with original URL
+				
+				consec_redirect_fails++;
+				
+				redirected_url = null;
+			}
+			
+			URL final_url = connection.getURL();
+			
+			if ( consec_redirect_fails < 10 && !original_url.toExternalForm().equals( final_url.toExternalForm())){
+				
+				redirected_url = final_url;
+			}
+			
+			last_response	= response;
+			
+			last_response_retry_after_secs	= -1;
+			
+            if ( response == 503 ){
+                           
+                	// webseed support for temp unavail - read the retry_after
+            	
+            	long retry_after_date = new Long(connection.getHeaderFieldDate("Retry-After", -1L)).longValue();
+            	
+                if ( retry_after_date <= -1 ){
+                	
+                	last_response_retry_after_secs = connection.getHeaderFieldInt("Retry-After", -1);
+                    
+                }else{
+                	
+                	last_response_retry_after_secs = (int)((retry_after_date - System.currentTimeMillis())/1000);
+                	
+                	if ( last_response_retry_after_secs < 0 ){
+                		
+                		last_response_retry_after_secs = -1;
+                	}
+                }
+            }
+            
+			is = connection.getInputStream();
+			
+			if ( 	response == HttpURLConnection.HTTP_ACCEPTED || 
+					response == HttpURLConnection.HTTP_OK ||
+					response == HttpURLConnection.HTTP_PARTIAL ){
+								
+				int	pos = 0;
+				
+				byte[]	buffer 		= null;
+				int		buffer_pos	= 0;
+				int		buffer_len	= 0;
+
+				while( pos < length ){
+					
+					if ( buffer == null ){
+						
+						buffer 		= listener.getBuffer();						
+						buffer_pos	= listener.getBufferPosition();
+						buffer_len	= listener.getBufferLength();
+					}
+
+					listener.setBufferPosition( buffer_pos );
+					
+					int	to_read = buffer_len - buffer_pos;
+					
+					int	permitted = listener.getPermittedBytes();
+					
+					if ( permitted < to_read ){
+						
+						to_read	= permitted;
+					}
+					
+					int	len = is.read( buffer, buffer_pos, to_read );
+					
+					if ( len < 0 ){
+						
+						break;
+					}
+					
+					listener.reportBytesRead( len );
+					
+					pos	+= len;
+					
+					buffer_pos	+= len;
+					
+					if ( buffer_pos == buffer_len ){
+						
+						listener.done();
+						
+						buffer		= null;
+						buffer_pos	= 0;
+					}
+				}
+				
+				if ( pos != length ){
+					
+					String	log_str;
+					
+					if ( buffer == null ){
+						
+						log_str = "No buffer assigned";
+						
+					}else{
+						
+						log_str =  new String( buffer, 0, length );
+						
+						if ( log_str.length() > 64 ){
+							
+							log_str = log_str.substring( 0, 64 );
+						}
+					}
+					
+					outcome = "Connection failed: data too short - " + length + "/" + pos + " [" + log_str + "]";
+					
+					throw( new ExternalSeedException( outcome ));
+				}
+				
+				outcome = "read " + pos + " bytes";
+				
+				// System.out.println( "download length: " + pos );
+				
+			}else{
+				
+				outcome = "Connection failed: " + connection.getResponseMessage();
+				
+				ExternalSeedException	error = new ExternalSeedException( outcome );
+				
+				error.setPermanentFailure( true );
+				
+				throw( error );
+			}
+		}catch( IOException e ){
+			
+			if ( con_fail_is_perm_fail && !connected ){
+				
+				outcome = "Connection failed: " + e.getMessage();
+				
+				ExternalSeedException	error = new ExternalSeedException( outcome );
+				
+				error.setPermanentFailure( true );
+				
+				throw( error );
+
+			}else{
+				
+				outcome =  "Connection failed: " + Debug.getNestedExceptionMessage( e );
+                
+                if ( last_response_retry_after_secs >= 0){
+                	
+                    outcome += ", Retry-After: " + last_response_retry_after_secs + " seconds";
+                }
+				                
+				ExternalSeedException excep = new ExternalSeedException( outcome, e );
+				
+				if ( e instanceof FileNotFoundException ){
+					
+					excep.setPermanentFailure( true );
+				}
+				
+				throw( excep );
+			}
+		}catch( Throwable e ){
+			
+			if ( e instanceof ExternalSeedException ){
+				
+				throw((ExternalSeedException)e);
+			}
+			
+			outcome = "Connection failed: " + Debug.getNestedExceptionMessage( e );
+			
+			throw( new ExternalSeedException("Connection failed", e ));
+			
+		}finally{
+			
+			SESecurityManager.unsetThreadPasswordHandler();
+
+			// System.out.println( "Done to " + url + ": " + Thread.currentThread().getId() + ", outcome=" + outcome );
+
+			if ( is != null ){
+				
+				try{
+					is.close();
+					
+				}catch( Throwable e ){
+					
+				}
+			}
+		}
+	}
+	
+	public void
+	downloadSocket(
+		int									length,
+		ExternalSeedHTTPDownloaderListener	listener,
+		boolean								con_fail_is_perm_fail )
+	        	
+	    throws ExternalSeedException
+	{
+		downloadSocket( new String[0], new String[0], length, listener, con_fail_is_perm_fail );
+	}
+	
+	public void
+	downloadSocket(
+		String[]							prop_names,
+		String[]							prop_values,
+		int									length,
+		ExternalSeedHTTPDownloaderListener	listener,
+		boolean								con_fail_is_perm_fail )
+	
+		throws ExternalSeedException
+	{
+		Socket	socket	= null;
+		
+		boolean	connected = false;
+		
+		try{				
+			String	output_header = 
+				"GET " + original_url.getPath() + "?" + original_url.getQuery() + " HTTP/1.1" + NL +
+				"Host: " + original_url.getHost() + (original_url.getPort()==-1?"":( ":" + original_url.getPort())) + NL +
+				"Accept: */*" + NL +
+				"Connection: Close" + NL +	// if we want to support keep-alive we'll need to implement a socket cache etc.
+				"User-Agent: " + user_agent + NL;
+		
+			for (int i=0;i<prop_names.length;i++){
+				
+				output_header += prop_names[i] + ":" + prop_values[i] + NL;
+			}
+			
+			output_header += NL;
+			
+			int	time_remaining	= listener.getPermittedTime();
+			
+			if ( time_remaining > 0 ){
+				
+				socket = new Socket();
+				
+				socket.connect( new InetSocketAddress( original_url.getHost(), original_url.getPort()==-1?original_url.getDefaultPort():original_url.getPort()), time_remaining );
+				
+			}else{
+		
+				socket = new Socket(  original_url.getHost(), original_url.getPort()==-1?original_url.getDefaultPort():original_url.getPort());
+			}
+			
+			connected	= true;
+			
+			time_remaining	= listener.getPermittedTime();
+
+			if ( time_remaining < 0 ){
+					
+				throw( new IOException( "Timeout during connect" ));
+				
+			}else if ( time_remaining > 0 ){
+				
+				socket.setSoTimeout( time_remaining );
+			}
+			
+			OutputStream	os = socket.getOutputStream();
+			
+			os.write( output_header.getBytes( "ISO-8859-1" ));
+			
+			os.flush();
+			
+			InputStream is = socket.getInputStream();
+			
+			try{
+				String	input_header = "";
+				
+				while( true ){
+					
+					byte[]	buffer = new byte[1];
+					
+					int	len = is.read( buffer );
+					
+					if ( len < 0 ){
+						
+						throw( new IOException( "input too short reading header" ));
+					}
+					
+					input_header	+= (char)buffer[0];
+					
+					if ( input_header.endsWith(NL+NL)){
+					
+						break;
+					}
+				}
+								
+				// HTTP/1.1 403 Forbidden
+				
+				int	line_end = input_header.indexOf(NL);
+				
+				if ( line_end == -1 ){
+					
+					throw( new IOException( "header too short" ));
+				}
+				
+				String	first_line = input_header.substring(0,line_end);
+				
+				StringTokenizer	tok = new StringTokenizer(first_line, " " );
+				
+				tok.nextToken();
+				
+				int	response = Integer.parseInt( tok.nextToken());
+				
+				last_response	= response;
+				
+				last_response_retry_after_secs	= -1;
+				
+				String	response_str	= tok.nextToken();				
+				
+				if ( 	response == HttpURLConnection.HTTP_ACCEPTED || 
+						response == HttpURLConnection.HTTP_OK ||
+						response == HttpURLConnection.HTTP_PARTIAL ){
+					
+					byte[]	buffer 		= null;
+					int		buffer_pos	= 0;
+					int		buffer_len	= 0;
+					
+					int	pos = 0;
+					
+					while( pos < length ){
+						
+						if ( buffer == null ){
+							
+							buffer 		= listener.getBuffer();							
+							buffer_pos	= listener.getBufferPosition();
+							buffer_len	= listener.getBufferLength();
+						}
+						
+						int	to_read = buffer_len - buffer_pos;
+						
+						int	permitted = listener.getPermittedBytes();
+						
+						if ( permitted < to_read ){
+							
+							to_read	= permitted;
+						}
+						
+						int	len = is.read( buffer, buffer_pos, to_read );
+						
+						if ( len < 0 ){
+							
+							break;
+						}
+						
+						listener.reportBytesRead( len );
+						
+						pos	+= len;
+						
+						buffer_pos	+= len;
+						
+						if ( buffer_pos == buffer_len ){
+							
+							listener.done();
+							
+							buffer		= null;
+							buffer_pos	= 0;
+						}
+					}
+					
+					if ( pos != length ){
+						
+						String	log_str;
+						
+						if ( buffer == null ){
+							
+							log_str = "No buffer assigned";
+							
+						}else{
+							
+							log_str =  new String( buffer, 0, buffer_pos>64?64:buffer_pos );
+						}
+						
+						throw( new ExternalSeedException("Connection failed: data too short - " + length + "/" + pos + " [last=" + log_str + "]" ));
+					}
+					
+					// System.out.println( "download length: " + pos );
+										
+				}else if ( 	response == 503 ){
+					
+						// webseed support for temp unavail - read the data
+					
+					String	data_str = "";
+					
+					while( true ){
+						
+						byte[]	buffer = new byte[1];
+						
+						int	len = is.read( buffer );
+						
+						if ( len < 0 ){
+							
+							break;
+						}
+						
+						data_str += (char)buffer[0];
+					}
+					
+					last_response_retry_after_secs = Integer.parseInt( data_str );
+				
+						// this gets trapped below and turned into an appropriate ExternalSeedException
+					
+					throw( new IOException( "Server overloaded" ));
+					
+				}else{
+					
+					ExternalSeedException	error = new ExternalSeedException("Connection failed: " + response_str );
+					
+					error.setPermanentFailure( true );
+					
+					throw( error );
+				}
+			}finally{
+				
+				is.close();
+			}
+			
+		}catch( IOException e ){
+			
+			if ( con_fail_is_perm_fail && !connected ){
+				
+				ExternalSeedException	error = new ExternalSeedException("Connection failed: " + e.getMessage());
+				
+				error.setPermanentFailure( true );
+				
+				throw( error );
+
+			}else{
+				
+				String outcome =  "Connection failed: " + Debug.getNestedExceptionMessage( e );
+
+				if ( last_response_retry_after_secs >= 0 ){
+	                	
+					outcome += ", Retry-After: " + last_response_retry_after_secs + " seconds";
+	            }
+
+				throw( new ExternalSeedException( outcome, e ));
+			}
+		}catch( Throwable e ){
+						
+			if ( e instanceof ExternalSeedException ){
+				
+				throw((ExternalSeedException)e);
+			}
+			
+			throw( new ExternalSeedException("Connection failed", e ));
+			
+		}finally{
+			
+			if ( socket != null ){
+				
+				try{
+					socket.close();
+					
+				}catch( Throwable e ){
+				}
+			}
+		}
+	}
+	
+	public void
+	deactivate()
+	{	
+	}
+	
+	public PasswordAuthentication
+	getAuthentication(
+		String		realm,
+		URL			tracker )
+	{
+		return( null );
+	}
+	
+	public void
+	setAuthenticationOutcome(
+		String		realm,
+		URL			tracker,
+		boolean		success )
+	{
+	}
+	
+	public void
+	clearPasswords()
+	{
+	}
+	
+	public int
+	getLastResponse()
+	{
+		return( last_response );
+	}
+	
+	public int
+	getLast503RetrySecs()
+	{
+		return( last_response_retry_after_secs );
+	}
+	
+	public static void
+	main(
+		String[]		args )
+	{
+		try{
+			String	url_str = "";
+			
+			ExternalSeedHTTPDownloader downloader = 
+		
+				new ExternalSeedHTTPDownloaderRange(
+						new URL( url_str ),
+						"Azureus" );
+				
+			downloader.downloadRange( 
+				0, 1,
+				new ExternalSeedHTTPDownloaderListener()
+				{
+					private int	position;
+					
+					public byte[]
+		        	getBuffer()
+		        	
+		        		throws ExternalSeedException
+		        	{
+						return( new byte[1024] );
+		        	}
+		        	
+		        	public void
+		        	setBufferPosition(
+		        		int	_position )
+		        	{
+		        		position = _position;
+		        	}
+		        	
+		        	public int
+		        	getBufferPosition()
+		        	{
+		        		return( position );
+		        	}
+		        	
+		        	public int
+		        	getBufferLength()
+		        	{
+		        		return( 1024 );
+		        	}
+		        	
+		        	public int
+		        	getPermittedBytes()
+		        	
+		        		throws ExternalSeedException
+		        	{
+		        		return( 1024 );
+		        	}
+		        	
+		        	public int
+		           	getPermittedTime()
+		        	{
+		        		return( Integer.MAX_VALUE );
+		        	}
+		        	
+		        	public void
+		        	reportBytesRead(
+		        		int		num )
+		        	{
+		        		System.out.println( "read " + num );
+		        	}
+		        	
+		        	public boolean 
+		        	isCancelled() 
+		        	{
+		        		return false;
+		        	}
+		        	
+		        	public void
+		        	done()
+		        	{
+		        		System.out.println( "done" );
+		        	}
+				},
+				true );
+			
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/com/aelitis/azureus/plugins/magnet/MagnetPlugin.java b/com/aelitis/azureus/plugins/magnet/MagnetPlugin.java
index e706598..9c48f51 100644
--- a/com/aelitis/azureus/plugins/magnet/MagnetPlugin.java
+++ b/com/aelitis/azureus/plugins/magnet/MagnetPlugin.java
@@ -549,14 +549,16 @@ MagnetPlugin
 							potential_contacts_mon.exit();
 						}
 						
-						AEThread2 t = 
-							new AEThread2( "MagnetPlugin:HitHandler", true )
+						contact.isAlive(
+							20*1000,
+							new DistributedDatabaseListener()
 							{
-								public void
-								run()
+								public void 
+								event(
+									DistributedDatabaseEvent event) 
 								{
 									try{
-										boolean	alive = contact.isAlive(20*1000);
+										boolean	alive = event.getType() == DistributedDatabaseEvent.ET_OPERATION_COMPLETE;
 																						
 										listener.reportActivity( 
 												getMessageText( alive?"report.alive":"report.dead",	contact.getName()));
@@ -609,9 +611,7 @@ MagnetPlugin
 										potential_contacts_sem.release();
 									}
 								}
-							};
-													
-						t.start();
+							});
 					}
 				};
 				
diff --git a/com/aelitis/azureus/plugins/net/buddy/BuddyPlugin.java b/com/aelitis/azureus/plugins/net/buddy/BuddyPlugin.java
index 53436f9..98c80ce 100644
--- a/com/aelitis/azureus/plugins/net/buddy/BuddyPlugin.java
+++ b/com/aelitis/azureus/plugins/net/buddy/BuddyPlugin.java
@@ -25,6 +25,7 @@ import java.io.*;
 import java.net.*;
 import java.util.*;
 
+
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerState;
@@ -567,18 +568,6 @@ BuddyPlugin
 				{
 					boolean enabled = enabled_param.getValue();
 
-					if (param != null && !enabled) {
-						UIInstance[] uis = plugin_interface.getUIManager().getUIInstances();
-						if (uis != null && uis.length > 0) {
-							int i = promptUserOnDisable(uis[0]);
-  						if (i != 0) {
-    						enabled_param.setValue(true);
-    						fireEnabledStateChanged();
-  							return;
-  						}
-						}
-					}
-					
 					nick_name_param.setEnabled( enabled );
 					
 						// only toggle overall state on a real change
@@ -674,38 +663,11 @@ BuddyPlugin
 					public void parameterChanged(
 							String parameterName) 
 					{
-						boolean enabled = COConfigurationManager.getBooleanParameter(parameterName);
-						if (enabled) {
-							fireEnabledStateChanged();
-							return;
-						}
-
-						if (promptUserOnDisable(ui) != 0) {
-							plugin_interface.getPluginState().setDisabled(false);
-							plugin_interface.getPluginState().setLoadedAtStartup(true);
-						} else {
-							fireEnabledStateChanged();
-						}
+						fireEnabledStateChanged();
 					}
 				});
 	}
 	
-	protected int
-	promptUserOnDisable(UIInstance ui)
-	{
-		if ("az2".equals(COConfigurationManager.getStringParameter("ui", "az3"))) {
-			return 0;
-		}
-		LocaleUtilities localeUtil = plugin_interface.getUtilities().getLocaleUtilities();
-		return ui.promptUser(
-				localeUtil.getLocalisedMessageText("azbuddy.ui.dialog.disable.title"),
-				localeUtil.getLocalisedMessageText("azbuddy.ui.dialog.disable.text"),
-				new String[] {
-					localeUtil.getLocalisedMessageText("Button.yes"),
-					localeUtil.getLocalisedMessageText("Button.no"),
-				}, 1);
-	}
-
 	public void
 	showConfig()
 	{
@@ -2002,71 +1964,97 @@ BuddyPlugin
 			List	buddies_config = (List)map.get( "friends" );
 				
 			if ( buddies_config != null ){
-							
-				for (int i=0;i<buddies_config.size();i++){
 					
-					Object o = buddies_config.get(i);
-		
-					if ( o instanceof Map ){
-						
-						Map	details = (Map)o;
-						
-						String	key = new String((byte[])details.get( "pk" ));
-						
-						List	recent_ygm = (List)details.get( "ygm" );
-											
-						String	nick = decodeString((byte[])details.get( "n" ));
-						
-						Long	l_seq = (Long)details.get( "ls" );
-						
-						int	last_seq = l_seq==null?0:l_seq.intValue();
-						
-						Long	l_lo = (Long)details.get( "lo" );
-						
-						long	last_time_online = l_lo==null?0:l_lo.longValue();
+				if ( buddies_config.size() == 0 ){
 					
-						if ( last_time_online > now ){
-							
-							last_time_online = now;
-						}
-						
-						Long l_subsystem = (Long)details.get( "ss" );
-						
-						int	subsystem = l_subsystem==null?SUBSYSTEM_AZ2:l_subsystem.intValue();
-						
-						Long l_ver = (Long)details.get("v");
-						
-						int	ver = l_ver==null?VERSION_INITIAL:l_ver.intValue();
-													
-						String	loc_cat = decodeString((byte[])details.get( "lc" ));
-						String	rem_cat = decodeString((byte[])details.get( "rc" ));
-						
-						BuddyPluginBuddy buddy = new BuddyPluginBuddy( this, subsystem, true, key, nick, ver, loc_cat, rem_cat, last_seq, last_time_online, recent_ygm );
-						
-						byte[]	ip_bytes = (byte[])details.get( "ip" );
+					deleteConfig();
+					
+				}else{
+					for (int i=0;i<buddies_config.size();i++){
 						
-						if ( ip_bytes != null ){
+						Object o = buddies_config.get(i);
+			
+						if ( o instanceof Map ){
 							
-							try{
-								InetAddress ip = InetAddress.getByAddress( ip_bytes );
+							Map	details = (Map)o;
+							
+							Long	l_ct = (Long)details.get( "ct" );
+							
+							long	created_time = l_ct==null?now:l_ct.longValue();
+							
+							if ( created_time > now ){
 								
-								int	tcp_port = ((Long)details.get( "tcp" )).intValue();
-								int	udp_port = ((Long)details.get( "udp" )).intValue();
+								created_time = now;
+							}
+							
+							String	key = new String((byte[])details.get( "pk" ));
+							
+							List	recent_ygm = (List)details.get( "ygm" );
+												
+							String	nick = decodeString((byte[])details.get( "n" ));
+							
+							Long	l_seq = (Long)details.get( "ls" );
+							
+							int	last_seq = l_seq==null?0:l_seq.intValue();
+							
+							Long	l_lo = (Long)details.get( "lo" );
+							
+							long	last_time_online = l_lo==null?0:l_lo.longValue();
+						
+							if ( last_time_online > now ){
 								
-								buddy.setCachedStatus( ip, tcp_port, udp_port );
+								last_time_online = now;
+							}
+							
+							Long l_subsystem = (Long)details.get( "ss" );
+							
+							int	subsystem = l_subsystem==null?SUBSYSTEM_AZ2:l_subsystem.intValue();
+							
+							if (subsystem == SUBSYSTEM_AZ3) {
+								continue;
+							}
+							
+							Long l_ver = (Long)details.get("v");
+							
+							int	ver = l_ver==null?VERSION_INITIAL:l_ver.intValue();
+														
+							String	loc_cat = decodeString((byte[])details.get( "lc" ));
+							String	rem_cat = decodeString((byte[])details.get( "rc" ));
+							
+							BuddyPluginBuddy buddy = new BuddyPluginBuddy( this, created_time, subsystem, true, key, nick, ver, loc_cat, rem_cat, last_seq, last_time_online, recent_ygm );
+							
+							byte[]	ip_bytes = (byte[])details.get( "ip" );
+							
+							if ( ip_bytes != null ){
 								
-							}catch( Throwable e ){
+								try{
+									InetAddress ip = InetAddress.getByAddress( ip_bytes );
+									
+									int	tcp_port = ((Long)details.get( "tcp" )).intValue();
+									int	udp_port = ((Long)details.get( "udp" )).intValue();
+									
+									buddy.setCachedStatus( ip, tcp_port, udp_port );
+									
+								}catch( Throwable e ){
+								}
 							}
+							
+							logMessage( "Loaded buddy " + buddy.getString());
+							
+							buddies.add( buddy );
+							
+							buddies_map.put( key, buddy );
 						}
-						
-						logMessage( "Loaded buddy " + buddy.getString());
-						
-						buddies.add( buddy );
-						
-						buddies_map.put( key, buddy );
 					}
 				}
 			}
+			
+			int	num_buddies = buddies.size();
+			
+			for ( BuddyPluginBuddy b: buddies ){
+				
+				b.setInitialStatus( now, num_buddies );
+			}
 		}
 	}
 	
@@ -2115,6 +2103,8 @@ BuddyPlugin
 					
 					Map	map = new HashMap();
 				
+					map.put( "ct", new Long( buddy.getCreatedTime()));
+					
 					map.put( "pk", buddy.getPublicKey());
 				
 					List	ygm = buddy.getYGMMarkers();
@@ -2170,9 +2160,16 @@ BuddyPlugin
 				
 				Map	map = new HashMap();
 				
-				map.put( "friends", buddies_config );
+				if ( buddies_config.size() > 0 ){
+				
+					map.put( "friends", buddies_config );
 				
-				writeConfig( map );
+					writeConfig( map );
+					
+				}else{
+					
+					deleteConfig();
+				}
 				
 				config_dirty = false;
 			}
@@ -2240,7 +2237,7 @@ BuddyPlugin
 			if ( buddy_to_return == null ){
 				
 				buddy_to_return = 
-					new BuddyPluginBuddy( this, subsystem, authorised, key, null, VERSION_CURRENT, null, null, 0, 0, null );
+					new BuddyPluginBuddy( this, SystemTime.getCurrentTime(), subsystem, authorised, key, null, VERSION_CURRENT, null, null, 0, 0, null );
 				
 				buddies.add( buddy_to_return );
 				
@@ -2305,11 +2302,25 @@ BuddyPlugin
 		writeConfigFile( config_file, map );
 	}
 	
+	protected void
+	deleteConfig()
+	{
+		File	config_file = new File( plugin_interface.getUtilities().getAzureusUserDir(), "friends.config" );
+		
+		Utilities utils = plugin_interface.getUtilities();
+			
+		plugin_interface.getUtilities().deleteResilientBEncodedFile(
+				config_file.getParentFile(), config_file.getName(), true );
+
+	}
+	
 	protected Map
 	readConfigFile(
 		File		name )
 	{
-		Map map = plugin_interface.getUtilities().readResilientBEncodedFile(
+		Utilities utils = plugin_interface.getUtilities();
+		
+		Map map = utils.readResilientBEncodedFile(
 						name.getParentFile(), name.getName(), true );
 		
 		if ( map == null ){
@@ -2325,8 +2336,10 @@ BuddyPlugin
 		File		name,
 		Map			data )
 	{
+		Utilities utils = plugin_interface.getUtilities();
+			
 		plugin_interface.getUtilities().writeResilientBEncodedFile(
-				name.getParentFile(), name.getName(), data, true );
+			name.getParentFile(), name.getName(), data, true );
 		
 		return( name.exists());
 	}
@@ -2452,7 +2465,9 @@ BuddyPlugin
 			
 			period += random.nextInt( 2*60*1000 );
 			
-			if ( last_check > now || now - last_check > period ){
+				// last check may be in the future as we defer checks for seemingly inactive buddies
+			
+			if ( now - last_check > period ){
 				
 				if ( !buddy.statusCheckActive()){
 			
diff --git a/com/aelitis/azureus/plugins/net/buddy/BuddyPluginBuddy.java b/com/aelitis/azureus/plugins/net/buddy/BuddyPluginBuddy.java
index 7fe893c..8dee85c 100644
--- a/com/aelitis/azureus/plugins/net/buddy/BuddyPluginBuddy.java
+++ b/com/aelitis/azureus/plugins/net/buddy/BuddyPluginBuddy.java
@@ -38,6 +38,7 @@ import org.gudy.azureus2.core3.util.Base32;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.DelayedEvent;
 import org.gudy.azureus2.core3.util.LightHashMap;
+import org.gudy.azureus2.core3.util.RandomUtils;
 import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.plugins.messaging.MessageException;
 import org.gudy.azureus2.plugins.messaging.generic.GenericMessageConnection;
@@ -70,6 +71,7 @@ BuddyPluginBuddy
 
 	
 	private BuddyPlugin		plugin;
+	private long			created_time;
 	private int				subsystem;
 	private boolean			authorised;
 	private String			public_key;
@@ -140,6 +142,7 @@ BuddyPluginBuddy
 	protected
 	BuddyPluginBuddy(
 		BuddyPlugin	_plugin,
+		long		_created_time,
 		int			_subsystem,
 		boolean		_authorised,
 		String		_pk,
@@ -152,6 +155,7 @@ BuddyPluginBuddy
 		List<Long>	_recent_ygm )
 	{
 		plugin				= _plugin;
+		created_time		= _created_time;
 		subsystem			= _subsystem;
 		authorised			= _authorised;
 		public_key 			= _pk;
@@ -166,6 +170,21 @@ BuddyPluginBuddy
 		persistent_msg_handler = new BuddyPluginBuddyMessageHandler( this, new File(plugin.getBuddyConfigDir(), public_key ));
 	}
 	
+	protected void
+	setInitialStatus(
+		long	now,
+		int		num_buddies )
+	{
+			// for inactive buddies we schedule their status checks so that on average we don't
+			// do more than one check every 5 minutes
+		
+		if ( 	last_time_online == 0 && 
+				now - created_time > 7*24*60*60*1000L ){
+			
+			last_status_check_time = now + RandomUtils.nextInt( 5*60*1000 * num_buddies );
+		}
+	}
+	
 	protected BuddyPlugin
 	getPlugin()
 	{
@@ -211,6 +230,12 @@ BuddyPluginBuddy
 		return( plugin.writeConfigFile( name, data ));
 	}
 	
+	protected long
+	getCreatedTime()
+	{
+		return( created_time );
+	}
+	
 	public int
 	getSubsystem()
 	{
diff --git a/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginView.java b/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginView.java
index 7573520..a97d5ca 100644
--- a/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginView.java
+++ b/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginView.java
@@ -202,13 +202,13 @@ BuddyPluginView
 			
 			status.setImageEnabled( true );
 			
-			status.setVisible( tracker.isEnabled());
-			label.setVisible( tracker.isEnabled());
-		
 			tracker.addListener( this );
 			
 			has_buddies = plugin.getBuddies().size() > 0;
 			
+			status.setVisible( tracker.isEnabled() && has_buddies);
+			label.setVisible( tracker.isEnabled() && has_buddies);
+		
 			/*
 			MenuItem mi = plugin.getPluginInterface().getUIManager().getMenuManager().addMenuItem(
 									status.getMenuContext(),
@@ -344,7 +344,7 @@ BuddyPluginView
 		protected synchronized void
 		updateStatus()
 		{
-			if ( tracker.isEnabled()){
+			if ( tracker.isEnabled() && has_buddies ){
 				
 				status.setVisible( true );
 				label.setVisible( true );
diff --git a/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewChat.java b/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewChat.java
index 7c12056..6f01af7 100644
--- a/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewChat.java
+++ b/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewChat.java
@@ -46,6 +46,7 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.utils.LocaleUtilities;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 
 import com.aelitis.azureus.plugins.net.buddy.BuddyPlugin;
@@ -79,7 +80,7 @@ BuddyPluginViewChat
 		
 		lu		= plugin.getPluginInterface().getUtilities().getLocaleUtilities();
 		
-		shell = new Shell( _display, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN | SWT.MAX );
+		shell = ShellFactory.createMainShell( SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN | SWT.MAX );
 
 		shell.addDisposeListener(
 			new DisposeListener()
diff --git a/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewInstance.java b/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewInstance.java
index 1c335ec..9b08c8e 100644
--- a/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewInstance.java
+++ b/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewInstance.java
@@ -24,6 +24,7 @@ package com.aelitis.azureus.plugins.net.buddy.swt;
 import java.net.InetAddress;
 import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.List;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyleRange;
@@ -31,45 +32,17 @@ import org.eclipse.swt.custom.StyledText;
 import org.eclipse.swt.dnd.Clipboard;
 import org.eclipse.swt.dnd.TextTransfer;
 import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.events.MenuEvent;
-import org.eclipse.swt.events.MenuListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.*;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.MenuItem;
-import org.eclipse.swt.widgets.Sash;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Text;
-import org.gudy.azureus2.core3.util.Base32;
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.DisplayFormatters;
-import org.gudy.azureus2.core3.util.SHA1Simple;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.PluginConfig;
 import org.gudy.azureus2.plugins.ui.UIInputReceiver;
+import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
 import org.gudy.azureus2.plugins.ui.UIInstance;
 import org.gudy.azureus2.plugins.utils.LocaleUtilities;
 import org.gudy.azureus2.ui.swt.Messages;
@@ -77,18 +50,9 @@ import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 
-import com.aelitis.azureus.core.security.CryptoHandler;
-import com.aelitis.azureus.core.security.CryptoManager;
-import com.aelitis.azureus.core.security.CryptoManagerFactory;
-import com.aelitis.azureus.core.security.CryptoManagerKeyListener;
+import com.aelitis.azureus.core.security.*;
 import com.aelitis.azureus.core.util.AZ3Functions;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPlugin;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPluginBuddy;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPluginBuddyMessage;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPluginBuddyMessageListener;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPluginBuddyRequestListener;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPluginException;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPluginListener;
+import com.aelitis.azureus.plugins.net.buddy.*;
 
 public class 
 BuddyPluginViewInstance 
@@ -838,7 +802,7 @@ BuddyPluginViewInstance
 				widgetSelected(
 					SelectionEvent event ) 
 				{
-					TableItem[] selection = buddy_table.getSelection();
+					final TableItem[] selection = buddy_table.getSelection();
 					
 					UIInputReceiver prompter = ui_instance.getInputReceiver();
 					
@@ -846,19 +810,22 @@ BuddyPluginViewInstance
 					prompter.setLocalisedMessage( lu.getLocalisedMessageText( "azbuddy.ui.menu.send_msg" ) );
 					
 					try{
-						prompter.prompt();
-						
-						String text = prompter.getSubmittedInput();
-						
-						if ( text != null ){
-						
-							for (int i=0;i<selection.length;i++){
+						prompter.prompt(new UIInputReceiverListener() {
+							public void UIInputReceiverClosed(UIInputReceiver prompter) {
+								String text = prompter.getSubmittedInput();
 								
-								BuddyPluginBuddy buddy = (BuddyPluginBuddy)selection[i].getData();
-								
-								plugin.getAZ2Handler().sendAZ2Message( buddy, text );
+								if ( text != null ){
+									
+									for (int i=0;i<selection.length;i++){
+										
+										BuddyPluginBuddy buddy = (BuddyPluginBuddy)selection[i].getData();
+										
+										plugin.getAZ2Handler().sendAZ2Message( buddy, text );
+									}
+								}
 							}
-						}
+						});
+						
 					}catch( Throwable e ){
 						
 					}
@@ -1255,28 +1222,31 @@ BuddyPluginViewInstance
 					prompter.setLocalisedTitle( lu.getLocalisedMessageText( "azbuddy.ui.menu.cat.set" ));
 					prompter.setLocalisedMessage( lu.getLocalisedMessageText( "azbuddy.ui.menu.cat.set_msg" ));
 					
-					prompter.prompt();
-					
-					String cats = prompter.getSubmittedInput();
-					
-					if ( cats != null ){
-					
-						cats = cats.trim();
-						
-						if ( cats.equalsIgnoreCase( "None" )){
+					prompter.prompt(new UIInputReceiverListener() {
+						public void UIInputReceiverClosed(UIInputReceiver prompter) {
+							String cats = prompter.getSubmittedInput();
 							
-							cats = "";
-						}
-						
-						TableItem[] selection = buddy_table.getSelection();
-						
-						for (int i=0;i<selection.length;i++){
-							
-							BuddyPluginBuddy buddy = (BuddyPluginBuddy)selection[i].getData();
-							
-							buddy.setLocalAuthorisedRSSCategories( cats );
+							if ( cats != null ){
+								
+								cats = cats.trim();
+								
+								if ( cats.equalsIgnoreCase( "None" )){
+									
+									cats = "";
+								}
+								
+								TableItem[] selection = buddy_table.getSelection();
+								
+								for (int i=0;i<selection.length;i++){
+									
+									BuddyPluginBuddy buddy = (BuddyPluginBuddy)selection[i].getData();
+									
+									buddy.setLocalAuthorisedRSSCategories( cats );
+								}
+							}
 						}
-					}
+					});
+					
 				};
 			});
 		
diff --git a/com/aelitis/azureus/plugins/removerules/DownloadRemoveRulesPlugin.java b/com/aelitis/azureus/plugins/removerules/DownloadRemoveRulesPlugin.java
index a561b58..1a3422d 100644
--- a/com/aelitis/azureus/plugins/removerules/DownloadRemoveRulesPlugin.java
+++ b/com/aelitis/azureus/plugins/removerules/DownloadRemoveRulesPlugin.java
@@ -41,7 +41,7 @@ import org.gudy.azureus2.core3.util.*;
 
 public class 
 DownloadRemoveRulesPlugin 
-	implements Plugin, DownloadManagerListener, HostNameToIPResolverListener
+	implements Plugin, DownloadManagerListener
 {
 	public static final int			INITIAL_DELAY			= 60*1000;
 	public static final int			DELAYED_REMOVAL_PERIOD	= 60*1000;
@@ -51,11 +51,8 @@ DownloadRemoveRulesPlugin
 	
 	public static final int			MAX_SEED_TO_PEER_RATIO	= 10;	// 10 to 1
 		
-	public static final String		AELITIS_HOST_CORE	= "aelitis.com";			// needs to be lowercase
-	public static final String		AELITIS_TRACKER		= "tracker.aelitis.com";	// needs to be lowercase
-	
-	protected String				aelitis_ip;
-	
+	public static final String		UPDATE_TRACKER		= "tracker.update.vuze.com";	// needs to be lowercase
+		
 	protected PluginInterface		plugin_interface;
 	protected boolean				closing;
 	
@@ -83,9 +80,7 @@ DownloadRemoveRulesPlugin
 		PluginInterface 	_plugin_interface )
 	{
 		plugin_interface	= _plugin_interface;
-		
-		HostNameToIPResolver.addResolverRequest( AELITIS_TRACKER, this );
-		
+				
 		log = plugin_interface.getLogger().getChannel("DLRemRules");
 
 		BasicPluginConfigModel	config = plugin_interface.getUIManager().createBasicPluginConfigModel( "torrents", "download.removerules.name" );
@@ -121,18 +116,6 @@ DownloadRemoveRulesPlugin
 	}
 	
 	public void
-	hostNameResolutionComplete(
-		InetAddress	address )
-	{
-			// resolution will fail if disconnected from net
-		
-		if ( address != null ){
-			
-			aelitis_ip	= address.getHostAddress();
-		}
-	}
-
-	public void
 	downloadAdded(
 		final Download	download )
 	{
@@ -250,13 +233,13 @@ DownloadRemoveRulesPlugin
 		
 			String	url_string = torrent.getAnnounceURL().toString().toLowerCase();
 			
-			if ( 	url_string.indexOf( AELITIS_HOST_CORE ) != -1 ||
-					( aelitis_ip != null && url_string.indexOf( aelitis_ip ) != -1 )){
+			if ( url_string.indexOf( UPDATE_TRACKER ) != -1 ){
 	
 					// emergency instruction from tracker
 				
-				if ( 	( download_completed && status.indexOf( "too many seeds" ) != -1 ) ||
-						status.indexOf( "too many peers" ) != -1 ){
+				if ( 	( download_completed && 
+							status.indexOf( "too many seeds" ) != -1 ) ||
+							status.indexOf( "too many peers" ) != -1 ){
 		
 					log.log(download.getTorrent(), LoggerChannel.LT_INFORMATION,
 							"Download '" + download.getName()
diff --git a/com/aelitis/azureus/plugins/sharing/hoster/ShareHosterPlugin.java b/com/aelitis/azureus/plugins/sharing/hoster/ShareHosterPlugin.java
index 766dd6e..2fe0946 100644
--- a/com/aelitis/azureus/plugins/sharing/hoster/ShareHosterPlugin.java
+++ b/com/aelitis/azureus/plugins/sharing/hoster/ShareHosterPlugin.java
@@ -54,9 +54,7 @@ ShareHosterPlugin
 	
 	protected Download			download_being_removed;
 	protected TrackerTorrent	torrent_being_removed;
-		
-	protected boolean			initialised	= false;
-	
+			
 	public static void
 	load(
 		PluginInterface		plugin_interface )
@@ -111,15 +109,6 @@ ShareHosterPlugin
 			
 			share_manager.initialise();
 			
-			initialised	= true;
-			
-			ShareResource[]	shares = share_manager.getShares();
-			
-			for ( int i=0;i<shares.length;i++){
-				
-				resourceAdded( shares[i] );
-			}
-			
 		}catch( ShareException e ){
 			
 			Debug.printStackTrace( e );
@@ -146,153 +135,150 @@ ShareHosterPlugin
 	resourceAdded(
 		final ShareResource		resource )
 	{
-		if ( initialised ){
+		log.log( LoggerChannel.LT_INFORMATION, "Resource added:".concat(resource.getName()));
+		
+		try{
 			
-			log.log( LoggerChannel.LT_INFORMATION, "Resource added:".concat(resource.getName()));
+			resource.addDeletionListener(
+				new ShareResourceWillBeDeletedListener()
+				{
+					public void
+					resourceWillBeDeleted(
+						ShareResource	resource )
+					
+						throws ShareResourceDeletionVetoException
+					{
+						canResourceBeDeleted( resource );
+					}
+				});
 			
-			try{
+			Download	new_download = null;
+			
+			int	type = resource.getType();
+			
+			if ( type == ShareResource.ST_FILE ){
 				
-				resource.addDeletionListener(
-					new ShareResourceWillBeDeletedListener()
-					{
-						public void
-						resourceWillBeDeleted(
-							ShareResource	resource )
-						
-							throws ShareResourceDeletionVetoException
-						{
-							canResourceBeDeleted( resource );
-						}
-					});
+				ShareResourceFile	file_resource = (ShareResourceFile)resource;
 				
-				Download	new_download = null;
+				ShareItem	item = file_resource.getItem();
+		
+				Torrent torrent = item.getTorrent();
 				
-				int	type = resource.getType();
+				Download	download = download_manager.getDownload( torrent );
 				
-				if ( type == ShareResource.ST_FILE ){
+				if ( download == null ){
 					
-					ShareResourceFile	file_resource = (ShareResourceFile)resource;
-					
-					ShareItem	item = file_resource.getItem();
+					new_download = download_manager.addNonPersistentDownload( torrent, item.getTorrentFile(), file_resource.getFile());
+				}
+			}else if ( type == ShareResource.ST_DIR ){
 			
-					Torrent torrent = item.getTorrent();
-					
-					Download	download = download_manager.getDownload( torrent );
-					
-					if ( download == null ){
-						
-						new_download = download_manager.addNonPersistentDownload( torrent, item.getTorrentFile(), file_resource.getFile());
-					}
-				}else if ( type == ShareResource.ST_DIR ){
+				ShareResourceDir	dir_resource = (ShareResourceDir)resource;
 				
-					ShareResourceDir	dir_resource = (ShareResourceDir)resource;
-					
-					ShareItem	item = dir_resource.getItem();
-					
-					Torrent torrent = item.getTorrent();
-					
-					Download	download = download_manager.getDownload( torrent );
+				ShareItem	item = dir_resource.getItem();
+				
+				Torrent torrent = item.getTorrent();
+				
+				Download	download = download_manager.getDownload( torrent );
+				
+				if ( download == null ){
 					
-					if ( download == null ){
-						
-						new_download = download_manager.addNonPersistentDownload( torrent, item.getTorrentFile(), dir_resource.getDir());
-					}
+					new_download = download_manager.addNonPersistentDownload( torrent, item.getTorrentFile(), dir_resource.getDir());
 				}
-				
-				if ( new_download != null ){
+			}
+			
+			if ( new_download != null ){
 
-					final Download	f_new_download = new_download;
-					
-					resource_dl_map.put( resource, new_download );
-					
-					resource.addChangeListener(
-						new ShareResourceListener()
+				final Download	f_new_download = new_download;
+				
+				resource_dl_map.put( resource, new_download );
+				
+				resource.addChangeListener(
+					new ShareResourceListener()
+					{
+						public void
+						shareResourceChanged(
+							ShareResource			resource,
+							ShareResourceEvent		event )
 						{
-							public void
-							shareResourceChanged(
-								ShareResource			resource,
-								ShareResourceEvent		event )
-							{
-								if ( event.getType() == ShareResourceEvent.ET_ATTRIBUTE_CHANGED ){
-							
-									TorrentAttribute	attribute = (TorrentAttribute)event.getData();
-									
-									// System.out.println( "sh: res -> ds: " + attribute.getName() + "/" + resource.getAttribute( attribute ));
-									
-									f_new_download.setAttribute(
-											attribute,
-											resource.getAttribute( attribute ));
-								}
-							}
-						});
-						
-					TorrentAttribute[]	attributes = resource.getAttributes();
-					
-					for (int i=0;i<attributes.length;i++){
+							if ( event.getType() == ShareResourceEvent.ET_ATTRIBUTE_CHANGED ){
 						
-						TorrentAttribute	ta = attributes[i];
-									
-						new_download.setAttribute( ta,	resource.getAttribute( ta ));
-					}
-					
-					new_download.addAttributeListener(
-						new DownloadAttributeListener() {
-							public void attributeEventOccurred(Download d, TorrentAttribute attr, int event_type){
-								resource.setAttribute(attr, d.getAttribute(attr));
+								TorrentAttribute	attribute = (TorrentAttribute)event.getData();
+								
+								// System.out.println( "sh: res -> ds: " + attribute.getName() + "/" + resource.getAttribute( attribute ));
+								
+								f_new_download.setAttribute(
+										attribute,
+										resource.getAttribute( attribute ));
 							}
-						},
-						plugin_interface.getTorrentManager().getAttribute(TorrentAttribute.TA_CATEGORY),
-						DownloadAttributeListener.WRITTEN
-					);
+						}
+					});
 					
-					Torrent	dl_torrent = new_download.getTorrent();
+				TorrentAttribute[]	attributes = resource.getAttributes();
+				
+				for (int i=0;i<attributes.length;i++){
 					
-					if ( dl_torrent != null ){
-						
-						TrackerTorrent	tt = tracker.host(dl_torrent, false );
-						
-						tt.addRemovalListener(
-								new TrackerTorrentWillBeRemovedListener()
-								{
-									public void
-									torrentWillBeRemoved(
-										TrackerTorrent	tt )
-									
-										throws TrackerTorrentRemovalVetoException
-									{
-										if ( tt != torrent_being_removed ){
-											
-											throw( new TrackerTorrentRemovalVetoException(
-													MessageText.getString("plugin.sharing.torrent.remove.veto")));
-										}
-									}								
-								});
-						
-						resource_tt_map.put( resource, tt );
-					}
+					TorrentAttribute	ta = attributes[i];
+								
+					new_download.setAttribute( ta,	resource.getAttribute( ta ));
+				}
+				
+				new_download.addAttributeListener(
+					new DownloadAttributeListener() {
+						public void attributeEventOccurred(Download d, TorrentAttribute attr, int event_type){
+							resource.setAttribute(attr, d.getAttribute(attr));
+						}
+					},
+					plugin_interface.getTorrentManager().getAttribute(TorrentAttribute.TA_CATEGORY),
+					DownloadAttributeListener.WRITTEN
+				);
+				
+				Torrent	dl_torrent = new_download.getTorrent();
+				
+				if ( dl_torrent != null ){
+					
+					TrackerTorrent	tt = tracker.host(dl_torrent, false );
 					
-					new_download.addDownloadWillBeRemovedListener(
-							new DownloadWillBeRemovedListener()
+					tt.addRemovalListener(
+							new TrackerTorrentWillBeRemovedListener()
 							{
 								public void
-								downloadWillBeRemoved(
-									Download	dl )
+								torrentWillBeRemoved(
+									TrackerTorrent	tt )
 								
-									throws DownloadRemovalVetoException
+									throws TrackerTorrentRemovalVetoException
 								{
-									if ( dl != download_being_removed ){
+									if ( tt != torrent_being_removed ){
 										
-										throw( new DownloadRemovalVetoException(
-													MessageText.getString("plugin.sharing.download.remove.veto")));
+										throw( new TrackerTorrentRemovalVetoException(
+												MessageText.getString("plugin.sharing.torrent.remove.veto")));
 									}
-								}
+								}								
 							});
+					
+					resource_tt_map.put( resource, tt );
 				}
 				
-			}catch( Throwable e ){
-				
-				Debug.printStackTrace( e );
+				new_download.addDownloadWillBeRemovedListener(
+						new DownloadWillBeRemovedListener()
+						{
+							public void
+							downloadWillBeRemoved(
+								Download	dl )
+							
+								throws DownloadRemovalVetoException
+							{
+								if ( dl != download_being_removed ){
+									
+									throw( new DownloadRemovalVetoException(
+												MessageText.getString("plugin.sharing.download.remove.veto")));
+								}
+							}
+						});
 			}
+			
+		}catch( Throwable e ){
+			
+			Debug.printStackTrace( e );
 		}
 	}
 	
@@ -343,16 +329,14 @@ ShareHosterPlugin
 	
 	public void
 	resourceModified(
-		ShareResource		resource )
+		ShareResource		old_resource,
+		ShareResource		new_resource )
 	{
-		log.log( LoggerChannel.LT_INFORMATION, "Resource modified:".concat(resource.getName()));
-		
-		if ( initialised ){
-			
-			resourceDeleted( resource );
+		log.log( LoggerChannel.LT_INFORMATION, "Resource modified:".concat(old_resource.getName()));
+					
+		resourceDeleted( old_resource );
 			
-			resourceAdded( resource );
-		}
+		resourceAdded( new_resource );
 	}
 	
 	public void
@@ -360,62 +344,59 @@ ShareHosterPlugin
 		ShareResource		resource )
 	{
 		log.log( LoggerChannel.LT_INFORMATION, "Resource deleted:".concat(resource.getName()));
+				
+		Download	dl = (Download)resource_dl_map.get(resource);
 		
-		if ( initialised ){
-		
-			Download	dl = (Download)resource_dl_map.get(resource);
+		if ( dl != null ){
 			
-			if ( dl != null ){
+			try{
+				download_being_removed	= dl;
+				
+					// the resource has gone! stop torrent if running to permit 
+					// deletion
 				
 				try{
-					download_being_removed	= dl;
-					
-						// the resource has gone! stop torrent if running to permit 
-						// deletion
-					
-					try{
-						dl.stop();
-						
-					}catch( Throwable e ){
-						
-						// ignore this as it might already be stopped
-					}
-					
-					dl.remove();
+					dl.stop();
 					
 				}catch( Throwable e ){
 					
-					Debug.printStackTrace( e );
-					
-				}finally{
-					
-					download_being_removed	= null;
+					// ignore this as it might already be stopped
 				}
 				
-				resource_dl_map.remove( resource );
-			}	
+				dl.remove();
+				
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace( e );
+				
+			}finally{
+				
+				download_being_removed	= null;
+			}
 			
-			TrackerTorrent	tt = (TrackerTorrent)resource_tt_map.get(resource);
+			resource_dl_map.remove( resource );
+		}	
+		
+		TrackerTorrent	tt = (TrackerTorrent)resource_tt_map.get(resource);
+		
+		if ( tt != null ){
 			
-			if ( tt != null ){
+			try{
+				torrent_being_removed	= tt;
 				
-				try{
-					torrent_being_removed	= tt;
-					
-					tt.remove();
-					
-				}catch( Throwable e ){
-					
-					Debug.printStackTrace( e );
-					
-				}finally{
-					
-					torrent_being_removed	= null;
-				}
+				tt.remove();
 				
-				resource_tt_map.remove( resource );
-			}	
-		}
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace( e );
+				
+			}finally{
+				
+				torrent_being_removed	= null;
+			}
+			
+			resource_tt_map.remove( resource );
+		}	
 	}
 
 	public void
diff --git a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/StartStopRulesDefaultPlugin.java b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/StartStopRulesDefaultPlugin.java
index ca39c4a..60a176a 100644
--- a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/StartStopRulesDefaultPlugin.java
+++ b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/StartStopRulesDefaultPlugin.java
@@ -25,9 +25,11 @@ import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationListener;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.config.impl.ConfigurationDefaults;
 import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.plugins.*;
+import org.gudy.azureus2.plugins.Plugin;
+import org.gudy.azureus2.plugins.PluginConfig;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.PluginListener;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.plugins.download.*;
 import org.gudy.azureus2.plugins.logging.LoggerChannel;
@@ -316,7 +318,7 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 		configModel.addBooleanParameter2("StartStopManager_bAutoReposition",
 				"ConfigView.label.seeding.autoReposition", false);
 		configModel.addIntParameter2("StartStopManager_iMinSeedingTime",
-				"ConfigView.label.minSeedingTime", 60 * 3);
+				"ConfigView.label.minSeedingTime", 60 * 10);
 
 		// ignore rules subsection
 		// ---------
@@ -492,6 +494,8 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 			}
 		}
 	}
+	
+	private volatile boolean immediateProcessingScheduled = false;
 
 	/** Listen to Download changes and recalc SR if needed 
 	 */
@@ -503,12 +507,17 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 			if (dlData != null) {
 				// force a SR recalc, so that it gets position properly next process()
 				requestProcessCycle(dlData);
-				if (new_state == Download.ST_READY || new_state == Download.ST_WAITING) {
-					new AEThread2("processReady", true) {
-						public void run() {
-							process();
-						}
-					}.start();
+				if ((new_state == Download.ST_READY || new_state == Download.ST_WAITING)) {
+					if (immediateProcessingScheduled) { 
+						requestProcessCycle(dlData);
+					} else {
+						immediateProcessingScheduled = true;
+						new AEThread2("processReady", true) {
+							public void run() {
+								process();
+							}
+						}.start();
+					}
 				}
 				
 				if (bDebugLog)
@@ -1371,6 +1380,8 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 				}
 				processLastComplete = now;
 			}
+			
+			immediateProcessingScheduled = false;
 
 			this_mon.exit();
 		}
diff --git a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionQueue.java b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionQueue.java
index 15a96b5..22f10b3 100644
--- a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionQueue.java
+++ b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionQueue.java
@@ -76,7 +76,6 @@ public class ConfigSectionQueue implements UISWTConfigSection
 		label = new Label(cSection, SWT.NULL);
 		Messages.setLanguageText(label, "ConfigView.label.maxdownloads");
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		final IntParameter maxDLs = new IntParameter(cSection, "max downloads");
 		maxDLs.setLayoutData(gridData);
 
@@ -85,7 +84,6 @@ public class ConfigSectionQueue implements UISWTConfigSection
 		label = new Label(cSection, SWT.NULL);
 		Messages.setLanguageText(label, "ConfigView.label.maxactivetorrents");
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		final IntParameter maxActiv = new IntParameter(cSection,
 				"max active torrents");
 		maxActiv.setLayoutData(gridData);
@@ -115,7 +113,6 @@ public class ConfigSectionQueue implements UISWTConfigSection
 		maxActiveWhenSeedingEnabled.setLayoutData(gridData);
 
 		gridData = new GridData();
-		gridData.widthHint = 40;
 
 		final IntParameter maxActivWhenSeeding = new IntParameter(
 				cMaxActiveOptionsArea, "StartStopManager_iMaxActiveTorrentsWhenSeeding");
@@ -126,7 +123,6 @@ public class ConfigSectionQueue implements UISWTConfigSection
 		label = new Label(cSection, SWT.NULL);
 		Messages.setLanguageText(label, "ConfigView.label.mindownloads");
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		final IntParameter minDLs = new IntParameter(cSection, "min downloads");
 		minDLs.setLayoutData(gridData);
 		minDLs.setMaximumValue(maxDLs.getValue() / 2);
diff --git a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeeding.java b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeeding.java
index e0df4f1..c4cad80 100644
--- a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeeding.java
+++ b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeeding.java
@@ -78,7 +78,6 @@ public class ConfigSectionSeeding implements UISWTConfigSection {
     label = new Label(cSeeding, SWT.NULL);
     Messages.setLanguageText(label, "ConfigView.label.minSeedingTime");
     gridData = new GridData();
-    gridData.widthHint = 40;
     new IntParameter(cSeeding, "StartStopManager_iMinSeedingTime").setLayoutData(gridData);
 
     gridData = new GridData();
@@ -99,7 +98,6 @@ public class ConfigSectionSeeding implements UISWTConfigSection {
     label = new Label(cSeeding, SWT.NULL);
     Messages.setLanguageText(label, "ConfigView.label.seeding.addForSeedingDLCopyCount");
     gridData = new GridData();
-    gridData.widthHint = 40;
     new IntParameter(cSeeding, "StartStopManager_iAddForSeedingDLCopyCount").setLayoutData(gridData);
 
     label = new Label(cSeeding, SWT.NULL);
@@ -115,7 +113,6 @@ public class ConfigSectionSeeding implements UISWTConfigSection {
     cArea.setLayoutData(gridData);
 
     gridData = new GridData();
-    gridData.widthHint = 20;
     final IntParameter paramFakeFullCopy = new IntParameter(cArea, "StartStopManager_iNumPeersAsFullCopy");
     paramFakeFullCopy.setLayoutData(gridData);
 
@@ -143,7 +140,6 @@ public class ConfigSectionSeeding implements UISWTConfigSection {
     Messages.setLanguageText(label, "ConfigView.label.seeding.fakeFullCopySeedStart");
 
     gridData = new GridData();
-    gridData.widthHint = 20;
     new IntParameter(cFullCopyOptionsArea, "StartStopManager_iFakeFullCopySeedStart").setLayoutData(gridData);
     label = new Label(cFullCopyOptionsArea, SWT.NULL);
     Messages.setLanguageText(label, "ConfigView.label.seeds");
diff --git a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingAutoStarting.java b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingAutoStarting.java
index b836b51..871230e 100644
--- a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingAutoStarting.java
+++ b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingAutoStarting.java
@@ -66,7 +66,6 @@ public class ConfigSectionSeedingAutoStarting implements UISWTConfigSection {
     Label label;
 
     Composite gQR = new Composite(parent, SWT.NULL);
-    gQR.addControlListener(new Utils.LabelWrapControlListener());
 
     layout = new GridLayout();
     layout.numColumns = 1;
@@ -122,7 +121,6 @@ public class ConfigSectionSeedingAutoStarting implements UISWTConfigSection {
     Messages.setLanguageText(label, "ConfigView.label.seeding.rankType.seed.fallback");
 
     gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
-    gridData.widthHint = 20;
     IntParameter intParamFallBack = new IntParameter(gSeedCount, "StartStopManager_iRankTypeSeedFallback");
     intParamFallBack.setLayoutData(gridData);
 
diff --git a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingFirstPriority.java b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingFirstPriority.java
index 9f935b6..033665b 100644
--- a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingFirstPriority.java
+++ b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingFirstPriority.java
@@ -69,7 +69,6 @@ public class ConfigSectionSeedingFirstPriority
     Composite cArea, cArea1;
 
     Composite cFirstPriorityArea = new Composite(parent, SWT.NULL);
-    cFirstPriorityArea.addControlListener(new Utils.LabelWrapControlListener());
 
     layout = new GridLayout();
     layout.numColumns = 2;
diff --git a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingIgnore.java b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingIgnore.java
index 4fece49..89dfbc0 100644
--- a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingIgnore.java
+++ b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/ui/swt/ConfigSectionSeedingIgnore.java
@@ -62,7 +62,6 @@ public class ConfigSectionSeedingIgnore implements UISWTConfigSection {
     Label label;
 
     Composite cIgnoreRules = new Composite(parent, SWT.NULL);
-    cIgnoreRules.addControlListener(new Utils.LabelWrapControlListener());
 
     layout = new GridLayout();
     layout.numColumns = 3;
@@ -89,16 +88,14 @@ public class ConfigSectionSeedingIgnore implements UISWTConfigSection {
     label = new Label(cIgnore, SWT.NULL);
     Messages.setLanguageText(label, "ConfigView.label.ignoreSeeds"); //$NON-NLS-1$
     gridData = new GridData();
-    gridData.widthHint = 20;
-    new IntParameter(cIgnore, "StartStopManager_iIgnoreSeedCount").setLayoutData(gridData);
+    new IntParameter(cIgnore, "StartStopManager_iIgnoreSeedCount", 0, 9999).setLayoutData(gridData);
     label = new Label(cIgnore, SWT.NULL);
     Messages.setLanguageText(label, "ConfigView.label.seeds");
 
     label = new Label(cIgnore, SWT.WRAP);
     Messages.setLanguageText(label, "ConfigView.label.seeding.ignoreRatioPeers"); //$NON-NLS-1$
     gridData = new GridData();
-    gridData.widthHint = 20;
-    new IntParameter(cIgnore, "Stop Peers Ratio").setLayoutData(gridData);
+    new IntParameter(cIgnore, "Stop Peers Ratio", 0, 9999).setLayoutData(gridData);
     label = new Label(cIgnore, SWT.NULL);
     Messages.setLanguageText(label, "ConfigView.label.peers");
 
@@ -122,8 +119,7 @@ public class ConfigSectionSeedingIgnore implements UISWTConfigSection {
     Messages.setLanguageText(label, "ConfigView.label.seeding.fakeFullCopySeedStart");
 
     gridData = new GridData();
-    gridData.widthHint = 20;
-    new IntParameter(cArea, "StartStopManager_iIgnoreRatioPeersSeedStart").setLayoutData(gridData);
+    new IntParameter(cArea, "StartStopManager_iIgnoreRatioPeersSeedStart", 0, 9999).setLayoutData(gridData);
     label = new Label(cArea, SWT.NULL);
     Messages.setLanguageText(label, "ConfigView.label.seeds");
 
@@ -131,7 +127,7 @@ public class ConfigSectionSeedingIgnore implements UISWTConfigSection {
     label = new Label(cIgnore, SWT.NULL);
     Messages.setLanguageText(label, "ConfigView.label.seeding.ignoreShareRatio");
     gridData = new GridData();
-    gridData.widthHint = 30;
+    gridData.widthHint = 50;
     new FloatParameter(cIgnore, "Stop Ratio", 1, -1, true, 1).setLayoutData(gridData);
     label = new Label(cIgnore, SWT.NULL);
     label.setText(":1");
@@ -156,8 +152,7 @@ public class ConfigSectionSeedingIgnore implements UISWTConfigSection {
     Messages.setLanguageText(label, "ConfigView.label.seeding.fakeFullCopySeedStart");
 
     gridData = new GridData();
-    gridData.widthHint = 20;
-    new IntParameter(cArea, "StartStopManager_iIgnoreShareRatioSeedStart").setLayoutData(gridData);
+    new IntParameter(cArea, "StartStopManager_iIgnoreShareRatioSeedStart", 0, 9999).setLayoutData(gridData);
     label = new Label(cArea, SWT.NULL);
     Messages.setLanguageText(label, "ConfigView.label.seeds");
 
diff --git a/com/aelitis/azureus/plugins/tracker/dht/DHTTrackerPlugin.java b/com/aelitis/azureus/plugins/tracker/dht/DHTTrackerPlugin.java
index 58ae903..52d297c 100644
--- a/com/aelitis/azureus/plugins/tracker/dht/DHTTrackerPlugin.java
+++ b/com/aelitis/azureus/plugins/tracker/dht/DHTTrackerPlugin.java
@@ -102,6 +102,11 @@ DHTTrackerPlugin
 	private static final int	INTERESTING_INIT_RAND_OTHERS	=   30*60*1000;
 	private static final int	INTERESTING_INIT_MIN_OTHERS		=    5*60*1000;
 
+	private static final int	INTERESTING_DHT_CHECK_PERIOD	= 1*60*60*1000;
+	private static final int	INTERESTING_DHT_INIT_RAND		=    5*60*1000;
+	private static final int	INTERESTING_DHT_INIT_MIN		=    2*60*1000;
+	
+	
 	private static final int	INTERESTING_AVAIL_MAX		= 8;	// won't pub if more
 	private static final int	INTERESTING_PUB_MAX_DEFAULT	= 30;	// limit on pubs
 	
@@ -123,6 +128,9 @@ DHTTrackerPlugin
 	private static final int	DL_DERIVED_MAX_TRACK		= 20;
 	private static final int	DIRECT_INJECT_PEER_MAX		= 5;
 	
+	private static boolean ADD_ASN_DERIVED_TARGET			= true;
+	private static boolean ADD_NETPOS_DERIVED_TARGETS		= false;
+	
 	private static URL	DEFAULT_URL;
 	
 	static{
@@ -523,9 +531,22 @@ DHTTrackerPlugin
 						}
 					}else{
 						
+						int	min;
+						int	rand;
+						
+						if ( TorrentUtils.isDecentralised( torrent.getAnnounceURL())){
+							
+							min		= INTERESTING_DHT_INIT_MIN;	
+							rand	= INTERESTING_DHT_INIT_RAND;
+
+						}else{
+							
+							min		= INTERESTING_INIT_MIN_OTHERS;	
+							rand	= INTERESTING_INIT_RAND_OTHERS;
+						}
+						
 						delay = plugin_interface.getUtilities().getCurrentSystemTime() + 
-									INTERESTING_INIT_MIN_OTHERS + 
-									random.nextInt( INTERESTING_INIT_RAND_OTHERS );
+									min + random.nextInt( rand );
 					}
 					
 					try{
@@ -2330,8 +2351,9 @@ DHTTrackerPlugin
 	protected void
 	processNonRegistrations()
 	{
-		Download	ready_download = null;
-	
+		Download	ready_download 				= null;
+		long		ready_download_next_check	= -1;
+		
 		long	now = plugin_interface.getUtilities().getCurrentSystemTime();
 		
 			// unfortunately getting scrape results can acquire locks and there is a vague
@@ -2402,7 +2424,7 @@ DHTTrackerPlugin
 					
 					if ( !force ){
 						
-						if ( !dht.isReachable()){
+						if ( false && !dht.isReachable()){
 							
 							continue;
 						}
@@ -2429,15 +2451,18 @@ DHTTrackerPlugin
 					
 					long	target = ((Long)interesting_downloads.get( download )).longValue();
 					
+					long check_period = TorrentUtils.isDecentralised( torrent.getAnnounceURL())?INTERESTING_DHT_CHECK_PERIOD:INTERESTING_CHECK_PERIOD;
+					
 					if ( target <= now ){
 						
-						ready_download	= download;
+						ready_download				= download;
+						ready_download_next_check 	= now + check_period;
 						
-						interesting_downloads.put( download, new Long( now + INTERESTING_CHECK_PERIOD ));
+						interesting_downloads.put( download, new Long( ready_download_next_check ));
 						
-					}else if ( target - now > INTERESTING_CHECK_PERIOD ){
+					}else if ( target - now > check_period ){
 						
-						interesting_downloads.put( download, new Long( now + (target%INTERESTING_CHECK_PERIOD)));
+						interesting_downloads.put( download, new Long( now + (target%check_period)));
 					}
 				}
 			}
@@ -2468,7 +2493,8 @@ DHTTrackerPlugin
 			
 				//System.out.println( "presence query for " + ready_download.getName());
 				
-				final long start = now;
+				final long start 		= now;
+				final long f_next_check = ready_download_next_check;
 				
 				dht.get(	ready_download.getTorrent().getHash(), 
 							"Presence query for '" + ready_download.getName() + "'",
@@ -2479,7 +2505,8 @@ DHTTrackerPlugin
 							new DHTPluginOperationListener()
 							{
 								private boolean diversified;
-								private int total = 0;
+								private int 	leechers = 0;
+								private int 	seeds	 = 0;
 								
 								public void
 								diversified()
@@ -2498,7 +2525,14 @@ DHTTrackerPlugin
 									DHTPluginContact	originator,
 									DHTPluginValue		value )
 								{
-									total++;
+									if (( value.getFlags() & DHTPlugin.FLAG_DOWNLOADING ) == 1 ){
+
+										leechers++;
+										
+									}else{
+										
+										seeds++;
+									}
 								}
 								
 								public void
@@ -2515,6 +2549,8 @@ DHTTrackerPlugin
 								{
 									// System.out.println( "    presence query for " + f_ready_download.getName() + "->" + total + "/div = " + diversified );
 	
+									int	total = leechers + seeds;
+									
 									log.log( f_ready_download.getTorrent(), LoggerChannel.LT_INFORMATION,
 											"Presence query for '" + f_ready_download.getName() + "': availability="+
 											(total==INTERESTING_AVAIL_MAX?(INTERESTING_AVAIL_MAX+"+"):(total+"")) + ",div=" + diversified +
@@ -2590,6 +2626,64 @@ DHTTrackerPlugin
 												});
 	
 									}
+									
+									f_ready_download.setScrapeResult(
+										new DownloadScrapeResult()
+										{
+											public Download
+											getDownload()
+											{
+												return( null );
+											}
+											
+											public int
+											getResponseType()
+											{
+												return( RT_SUCCESS );
+											}
+											
+											public int
+											getSeedCount()
+											{
+												return( seeds );
+											}
+											
+											public int
+											getNonSeedCount()
+											{
+												return( leechers );
+											}
+	
+											public long
+											getScrapeStartTime()
+											{
+												return( SystemTime.getCurrentTime());
+											}
+												
+											public void 
+											setNextScrapeStartTime(
+												long nextScrapeStartTime)
+											{
+											}
+											
+											public long
+											getNextScrapeStartTime()
+											{
+												return( f_next_check );
+											}
+											
+											public String
+											getStatus()
+											{
+												return( "OK" );
+											}
+	
+											public URL
+											getURL()
+											{
+												return( f_ready_download.getTorrent().getAnnounceURL());
+											}
+										});
 								}
 							});
 	
@@ -2671,6 +2765,7 @@ DHTTrackerPlugin
 		}
 	}
 	
+	/*
 	public DownloadScrapeResult
 	scrape(
 		byte[]		hash )
@@ -2790,6 +2885,7 @@ DHTTrackerPlugin
 					}
 				});
 	}
+	*/
 	
 	protected void
 	increaseActive(
@@ -2993,7 +3089,7 @@ DHTTrackerPlugin
 			}
 		}
 		
-		protected boolean
+		protected void
     	getTrackerTargets(
     		Download		download,
     		int				type )
@@ -3007,129 +3103,134 @@ DHTTrackerPlugin
     			result.add( new trackerTarget( torrent_hash, REG_TYPE_FULL, "" ));
     		}
     		
-    	    NetworkAdminASN net_asn = NetworkAdmin.getSingleton().getCurrentASN();
-    	      
-    	    String	as 	= net_asn.getAS();
-    	    String	asn = net_asn.getASName();
-
-    		if ( as.length() > 0 && asn.length() > 0 ){
-    			 
-    			String	key = "azderived:asn:" + as;
-    			
-    			try{
-    				byte[] asn_bytes = key.getBytes( "UTF-8" );
+    		if ( ADD_ASN_DERIVED_TARGET ){
     			
-    				byte[] key_bytes = new byte[torrent_hash.length + asn_bytes.length];
-    				
-    				System.arraycopy( torrent_hash, 0, key_bytes, 0, torrent_hash.length );
-    				
-    				System.arraycopy( asn_bytes, 0, key_bytes, torrent_hash.length, asn_bytes.length );
-    				
-    				result.add( new trackerTarget( key_bytes, REG_TYPE_DERIVED, asn + "/" + as ));
-    				
-    			}catch( Throwable e ){
-    				
-    				Debug.printStackTrace(e);
-    			}
-    		}
-    		
-    		long	now = SystemTime.getMonotonousTime();
-    		
-    		boolean	do_it;
-    		
-       		Long	metric = (Long)download.getUserData( DL_DERIVED_METRIC_KEY );
-       	 
-       		boolean	do_it_now = metric != null;
-       		
-    		if ( derived_active_start >= 0 && now - derived_active_start <= DERIVED_ACTIVE_MIN_MILLIS ){
-    			
-    			do_it = true;
-    			
-    			if ( metric == null ){
-    				
-    				metric = new Long( previous_metric );
-    			}
-    		}else{
-    			
-    			if ( do_it_now ){
-    				
-    				do_it = true;
-    				
-    			}else{
-    				
-    				derived_active_start = -1;
-    				
-    				do_it = false;
-    			}
-    		}
-    		
-    		boolean	newly_active = false;
-    		
-    		if ( do_it_now ){
-    			
-    			newly_active = derived_active_start == -1;
-    			
-    			derived_active_start = now;
+	    	    NetworkAdminASN net_asn = NetworkAdmin.getSingleton().getCurrentASN();
+	    	      
+	    	    String	as 	= net_asn.getAS();
+	    	    String	asn = net_asn.getASName();
+	
+	    		if ( as.length() > 0 && asn.length() > 0 ){
+	    			 
+	    			String	key = "azderived:asn:" + as;
+	    			
+	    			try{
+	    				byte[] asn_bytes = key.getBytes( "UTF-8" );
+	    			
+	    				byte[] key_bytes = new byte[torrent_hash.length + asn_bytes.length];
+	    				
+	    				System.arraycopy( torrent_hash, 0, key_bytes, 0, torrent_hash.length );
+	    				
+	    				System.arraycopy( asn_bytes, 0, key_bytes, torrent_hash.length, asn_bytes.length );
+	    				
+	    				result.add( new trackerTarget( key_bytes, REG_TYPE_DERIVED, asn + "/" + as ));
+	    				
+	    			}catch( Throwable e ){
+	    				
+	    				Debug.printStackTrace(e);
+	    			}
+	    		}
     		}
-     		  
-    		List<trackerTarget>	skipped_targets = null;
     		
-    		if ( do_it ){
-    			
-    			previous_metric = metric.longValue();
-    			
-	    		try{
-	    			DHTNetworkPosition[] positions = getNetworkPositions();
+    		if ( ADD_NETPOS_DERIVED_TARGETS ){
+	    			
+	    		long	now = SystemTime.getMonotonousTime();
+	    		
+	    		boolean	do_it;
 	    		
-	    			for (int i=0;i<positions.length;i++){
+	       		Long	metric = (Long)download.getUserData( DL_DERIVED_METRIC_KEY );
+	       	 
+	       		boolean	do_it_now = metric != null;
+	       		
+	    		if ( derived_active_start >= 0 && now - derived_active_start <= DERIVED_ACTIVE_MIN_MILLIS ){
+	    			
+	    			do_it = true;
+	    			
+	    			if ( metric == null ){
+	    				
+	    				metric = new Long( previous_metric );
+	    			}
+	    		}else{
+	    			
+	    			if ( do_it_now ){
+	    				
+	    				do_it = true;
 	    				
-	    				DHTNetworkPosition pos = positions[i];
+	    			}else{
 	    				
-	    				if ( pos.getPositionType() == DHTNetworkPosition.POSITION_TYPE_VIVALDI_V2 ){
-	    					
-	    					if ( pos.isValid()){
-	    						
-	    						List<Object[]>	derived_results = getVivaldiTargets( torrent_hash, pos.getLocation());
-	    						
-	    		    			int	num_to_add = metric.intValue() * derived_results.size() / 100;
-    				 			
-	    		    			// System.out.println( download.getName() + ": metric=" + metric + ", adding=" + num_to_add );
-	    		    			
-	    						for (int j=0;j<derived_results.size();j++){
-	    							
-	    							Object[] entry = derived_results.get(j);
-	    							
-	    							// int	distance = ((Integer)entry[0]).intValue();
-	    							
-	    							trackerTarget	target= (trackerTarget)entry[1];
-	    								    						
-	    							if ( j < num_to_add ){
-	    							
-	    								result.add( target );
-	    								
-	    							}else{
-	    								
-	    								if ( skipped_targets == null ){
-	    									
-	    									skipped_targets = new ArrayList<trackerTarget>();
-	    								}
-	    								
-	    								skipped_targets.add( target );
-	    							}
-	    						}
-	    					}
-	    				}
+	    				derived_active_start = -1;
+	    				
+	    				do_it = false;
 	    			}
-	    		}catch( Throwable e ){
+	    		}
+	    		
+	    		boolean	newly_active = false;
+	    		
+	    		if ( do_it_now ){
+	    			
+	    			newly_active = derived_active_start == -1;
 	    			
-	    			Debug.printStackTrace(e);
+	    			derived_active_start = now;
+	    		}
+	     		  
+	    		List<trackerTarget>	skipped_targets = null;
+	    		
+	    		if ( do_it ){
+	    			
+	    			previous_metric = metric.longValue();
+	    			
+		    		try{
+		    			DHTNetworkPosition[] positions = getNetworkPositions();
+		    		
+		    			for (int i=0;i<positions.length;i++){
+		    				
+		    				DHTNetworkPosition pos = positions[i];
+		    				
+		    				if ( pos.getPositionType() == DHTNetworkPosition.POSITION_TYPE_VIVALDI_V2 ){
+		    					
+		    					if ( pos.isValid()){
+		    						
+		    						List<Object[]>	derived_results = getVivaldiTargets( torrent_hash, pos.getLocation());
+		    						
+		    		    			int	num_to_add = metric.intValue() * derived_results.size() / 100;
+	    				 			
+		    		    			// System.out.println( download.getName() + ": metric=" + metric + ", adding=" + num_to_add );
+		    		    			
+		    						for (int j=0;j<derived_results.size();j++){
+		    							
+		    							Object[] entry = derived_results.get(j);
+		    							
+		    							// int	distance = ((Integer)entry[0]).intValue();
+		    							
+		    							trackerTarget	target= (trackerTarget)entry[1];
+		    								    						
+		    							if ( j < num_to_add ){
+		    							
+		    								result.add( target );
+		    								
+		    							}else{
+		    								
+		    								if ( skipped_targets == null ){
+		    									
+		    									skipped_targets = new ArrayList<trackerTarget>();
+		    								}
+		    								
+		    								skipped_targets.add( target );
+		    							}
+		    						}
+		    					}
+		    				}
+		    			}
+		    		}catch( Throwable e ){
+		    			
+		    			Debug.printStackTrace(e);
+		    		}
 	    		}
-    		}
     		
-    		put_targets 	= result.toArray( new trackerTarget[result.size()]);
-    		not_put_targets = skipped_targets;
+	    		not_put_targets = skipped_targets;
+    		}
     		
-    		return( newly_active );
+	    	put_targets 	= result.toArray( new trackerTarget[result.size()]);
     	}
 	}
 	
diff --git a/com/aelitis/azureus/ui/UIFunctions.java b/com/aelitis/azureus/ui/UIFunctions.java
index bdd2ad9..84e9497 100644
--- a/com/aelitis/azureus/ui/UIFunctions.java
+++ b/com/aelitis/azureus/ui/UIFunctions.java
@@ -51,6 +51,7 @@ public interface UIFunctions
 	public static final int VIEW_MYTRACKER = 9;
 	public static final int VIEW_ALLPEERS = 10;
 	public static final int VIEW_DETAILED_LISTVIEW = 11;
+	public static final int VIEW_PEERS_STATS = 12;
 	
 	public static final int ACTION_FULL_UPDATE	= 1;	// arg: String - url; response Boolean - ok
 	
@@ -112,9 +113,9 @@ public interface UIFunctions
 	public UIFunctionsUserPrompter getUserPrompter(String title, String text,
 			String[] buttons, int defaultOption);
 
-	public int promptUser(String title, String text, String[] buttons,
+	public void promptUser(String title, String text, String[] buttons,
 			int defaultOption, String rememberID, String rememberText,
-			boolean bRememberByDefault, int autoCloseInMS);
+			boolean bRememberByDefault, int autoCloseInMS, UserPrompterResultListener l);
 	
 	/**
 	 * Retrieves the class that handles periodically updating the UI
diff --git a/com/aelitis/azureus/ui/UIFunctionsUserPrompter.java b/com/aelitis/azureus/ui/UIFunctionsUserPrompter.java
index f0f0d99..eca2a17 100644
--- a/com/aelitis/azureus/ui/UIFunctionsUserPrompter.java
+++ b/com/aelitis/azureus/ui/UIFunctionsUserPrompter.java
@@ -20,6 +20,7 @@
 
 package com.aelitis.azureus.ui;
 
+
 /**
  * @author TuxPaper
  * @created Mar 18, 2007
@@ -71,11 +72,11 @@ public interface UIFunctionsUserPrompter
 	/**
 	 * Opens the prompt.  returns when user has chosen an action, or auto-close
 	 * 
-	 * @return Button number the user pressed
-	 *
 	 * @since 3.0.0.9
 	 */
-	int open();
+	void open(UserPrompterResultListener l);
+	
+	int waitUntilClosed();
 
 	/**
 	 * Sets the # of milliseconds before auto closing. 
@@ -99,9 +100,9 @@ public interface UIFunctionsUserPrompter
 	 * @param rememberID
 	 * @param rememberByDefault
 	 *
-	 * @since 3.0.0.9
+	 * @since 4.2.0.9
 	 */
-	void setRememberID(String rememberID, boolean rememberByDefault);
+	void setRemember(String rememberID, boolean rememberByDefault, String rememberText);
 
 	/**
 	 * @param rememberText
diff --git a/com/aelitis/azureus/ui/UserPrompterResultListener.java b/com/aelitis/azureus/ui/UserPrompterResultListener.java
new file mode 100644
index 0000000..3c6aba3
--- /dev/null
+++ b/com/aelitis/azureus/ui/UserPrompterResultListener.java
@@ -0,0 +1,6 @@
+package com.aelitis.azureus.ui;
+
+public interface UserPrompterResultListener
+{
+	public void prompterClosed(int result);
+}
diff --git a/com/aelitis/azureus/ui/common/table/TableColumnCore.java b/com/aelitis/azureus/ui/common/table/TableColumnCore.java
index 3fe6763..2bf6440 100644
--- a/com/aelitis/azureus/ui/common/table/TableColumnCore.java
+++ b/com/aelitis/azureus/ui/common/table/TableColumnCore.java
@@ -352,4 +352,6 @@ public interface TableColumnCore
 	 * @since 4.0.0.5
 	 */
 	List<TableColumnExtraInfoListener> getColumnExtraInfoListeners();
+
+	void reset();
 }
diff --git a/com/aelitis/azureus/ui/common/table/TableView.java b/com/aelitis/azureus/ui/common/table/TableView.java
index 2db582a..80f9f57 100644
--- a/com/aelitis/azureus/ui/common/table/TableView.java
+++ b/com/aelitis/azureus/ui/common/table/TableView.java
@@ -46,7 +46,6 @@ public interface TableView<DATASOURCETYPE>
 	 * You can't add datasources until the table is initialized
 	 * 
 	 * @param dataSource data source to add to the table
-	 * @param bImmediate Add immediately, or queue and add at next refresh
 	 */
 	void addDataSource(DATASOURCETYPE dataSource);
 
@@ -57,7 +56,6 @@ public interface TableView<DATASOURCETYPE>
 	 * You can't add datasources until the table is initialized
 	 * 
 	 * @param dataSources
-	 * @param bImmediate Add immediately, or queue and add at next refresh
 	 */
 	void addDataSources(DATASOURCETYPE[] dataSources);
 
@@ -275,24 +273,12 @@ public interface TableView<DATASOURCETYPE>
 	TableRowCore getRow(int x, int y);
 
 	/**
-	 * @param datasource
-	 * @param immediate
-	 */
-	void addDataSource(DATASOURCETYPE datasource, boolean immediate);
-
-	/**
 	 * @param dataSource
 	 * @return
 	 */
 	boolean dataSourceExists(DATASOURCETYPE dataSource);
 
 	/**
-	 * @param datasource
-	 * @param immediate
-	 */
-	void removeDataSource(DATASOURCETYPE datasource, boolean immediate);
-
-	/**
 	 * @return
 	 */
 	TableColumnCore[] getVisibleColumns();
diff --git a/com/aelitis/azureus/ui/common/table/impl/TableColumnImpl.java b/com/aelitis/azureus/ui/common/table/impl/TableColumnImpl.java
index 33cc004..899bd2d 100644
--- a/com/aelitis/azureus/ui/common/table/impl/TableColumnImpl.java
+++ b/com/aelitis/azureus/ui/common/table/impl/TableColumnImpl.java
@@ -74,6 +74,8 @@ public class TableColumnImpl
 
 	private int iWidth;
 
+	private int iDefaultWidth;
+
 	private int iInterval;
 
 	private long lLastSortValueChange;
@@ -216,7 +218,7 @@ public class TableColumnImpl
 
 		this.iAlignment = iAlignment;
 		setPosition(iPosition);
-		this.iWidth = iWidth;
+		this.iWidth = this.iDefaultWidth = iWidth;
 		this.iMinWidth = 16;
 		this.iInterval = iInterval;
 	}
@@ -229,7 +231,7 @@ public class TableColumnImpl
 
 		this.iAlignment = iAlignment;
 		setPosition(iPosition);
-		this.iWidth = iWidth;
+		this.iWidth = this.iDefaultWidth = iWidth;
 		this.iMinWidth = 16;
 	}
 
@@ -279,6 +281,9 @@ public class TableColumnImpl
 		//		}
 
 		iWidth = width;
+		if (iDefaultWidth == 0) {
+			iDefaultWidth = width;
+		}
 
 		if (bColumnAdded && bVisible) {
 			triggerColumnSizeChange();
@@ -1445,4 +1450,9 @@ public class TableColumnImpl
 		this.forPluginDataSourceType = forDataSourceType;
 	}
 
+	public void reset() {
+		if (iDefaultWidth != 0) {
+			setWidth(iDefaultWidth);
+		}
+	}
 }
diff --git a/com/aelitis/azureus/ui/common/table/impl/TableViewImpl.java b/com/aelitis/azureus/ui/common/table/impl/TableViewImpl.java
index d041c86..39e8e23 100644
--- a/com/aelitis/azureus/ui/common/table/impl/TableViewImpl.java
+++ b/com/aelitis/azureus/ui/common/table/impl/TableViewImpl.java
@@ -119,7 +119,11 @@ public abstract class TableViewImpl<DATASOURCETYPE>
 		Object[] listeners = listenersSelection.toArray();
 		for (int i = 0; i < listeners.length; i++) {
 			TableSelectionListener l = (TableSelectionListener) listeners[i];
-			l.deselected(rows);
+			try {
+				l.deselected(rows);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
 		}
 	}
 
diff --git a/com/aelitis/azureus/ui/images/btn_details.png b/com/aelitis/azureus/ui/images/btn_details.png
deleted file mode 100644
index c55b013..0000000
Binary files a/com/aelitis/azureus/ui/images/btn_details.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/buddy_add.png b/com/aelitis/azureus/ui/images/buddy_add.png
deleted file mode 100644
index 792adef..0000000
Binary files a/com/aelitis/azureus/ui/images/buddy_add.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/buddy_add_to_share.png b/com/aelitis/azureus/ui/images/buddy_add_to_share.png
deleted file mode 100644
index 7708b5e..0000000
Binary files a/com/aelitis/azureus/ui/images/buddy_add_to_share.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/buddy_add_to_share_selected.png b/com/aelitis/azureus/ui/images/buddy_add_to_share_selected.png
deleted file mode 100644
index 772b55f..0000000
Binary files a/com/aelitis/azureus/ui/images/buddy_add_to_share_selected.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/buddy_default_avatar.png b/com/aelitis/azureus/ui/images/buddy_default_avatar.png
deleted file mode 100644
index 0e45215..0000000
Binary files a/com/aelitis/azureus/ui/images/buddy_default_avatar.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/buddy_prompt_image.png b/com/aelitis/azureus/ui/images/buddy_prompt_image.png
deleted file mode 100644
index b0d495b..0000000
Binary files a/com/aelitis/azureus/ui/images/buddy_prompt_image.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/buddy_remove-over.png b/com/aelitis/azureus/ui/images/buddy_remove-over.png
deleted file mode 100644
index 29096d1..0000000
Binary files a/com/aelitis/azureus/ui/images/buddy_remove-over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/buddy_remove.png b/com/aelitis/azureus/ui/images/buddy_remove.png
deleted file mode 100644
index abc329f..0000000
Binary files a/com/aelitis/azureus/ui/images/buddy_remove.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_dialog_center-over.png b/com/aelitis/azureus/ui/images/button_dialog_center-over.png
deleted file mode 100644
index 3c81673..0000000
Binary files a/com/aelitis/azureus/ui/images/button_dialog_center-over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_dialog_center.png b/com/aelitis/azureus/ui/images/button_dialog_center.png
deleted file mode 100644
index 8194cc7..0000000
Binary files a/com/aelitis/azureus/ui/images/button_dialog_center.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_dialog_close-over.png b/com/aelitis/azureus/ui/images/button_dialog_close-over.png
deleted file mode 100644
index 929d024..0000000
Binary files a/com/aelitis/azureus/ui/images/button_dialog_close-over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_dialog_close.png b/com/aelitis/azureus/ui/images/button_dialog_close.png
deleted file mode 100644
index 3a73102..0000000
Binary files a/com/aelitis/azureus/ui/images/button_dialog_close.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_dialog_left-over.png b/com/aelitis/azureus/ui/images/button_dialog_left-over.png
deleted file mode 100644
index 34e810e..0000000
Binary files a/com/aelitis/azureus/ui/images/button_dialog_left-over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_dialog_left.png b/com/aelitis/azureus/ui/images/button_dialog_left.png
deleted file mode 100644
index dd0c9a9..0000000
Binary files a/com/aelitis/azureus/ui/images/button_dialog_left.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_dialog_min-over.png b/com/aelitis/azureus/ui/images/button_dialog_min-over.png
deleted file mode 100644
index 1cc18ea..0000000
Binary files a/com/aelitis/azureus/ui/images/button_dialog_min-over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_dialog_min.png b/com/aelitis/azureus/ui/images/button_dialog_min.png
deleted file mode 100644
index 4aacb5c..0000000
Binary files a/com/aelitis/azureus/ui/images/button_dialog_min.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_dialog_right-over.png b/com/aelitis/azureus/ui/images/button_dialog_right-over.png
deleted file mode 100644
index e18ed4a..0000000
Binary files a/com/aelitis/azureus/ui/images/button_dialog_right-over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_dialog_right.png b/com/aelitis/azureus/ui/images/button_dialog_right.png
deleted file mode 100644
index 0e477d9..0000000
Binary files a/com/aelitis/azureus/ui/images/button_dialog_right.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_skin_close-over.png b/com/aelitis/azureus/ui/images/button_skin_close-over.png
deleted file mode 100644
index 929d024..0000000
Binary files a/com/aelitis/azureus/ui/images/button_skin_close-over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/button_skin_close.png b/com/aelitis/azureus/ui/images/button_skin_close.png
deleted file mode 100644
index 3a73102..0000000
Binary files a/com/aelitis/azureus/ui/images/button_skin_close.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/chatNotification.png b/com/aelitis/azureus/ui/images/chatNotification.png
deleted file mode 100644
index a13eb45..0000000
Binary files a/com/aelitis/azureus/ui/images/chatNotification.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/clock_wait.png b/com/aelitis/azureus/ui/images/clock_wait.png
deleted file mode 100644
index 1ef3686..0000000
Binary files a/com/aelitis/azureus/ui/images/clock_wait.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/device_bel_logo.png b/com/aelitis/azureus/ui/images/device_bel_logo.png
new file mode 100644
index 0000000..9f07ab5
Binary files /dev/null and b/com/aelitis/azureus/ui/images/device_bel_logo.png differ
diff --git a/com/aelitis/azureus/ui/images/friend_online_icon.png b/com/aelitis/azureus/ui/images/friend_online_icon.png
deleted file mode 100644
index 618266a..0000000
Binary files a/com/aelitis/azureus/ui/images/friend_online_icon.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/grey_bubble.png b/com/aelitis/azureus/ui/images/grey_bubble.png
deleted file mode 100644
index bae40ca..0000000
Binary files a/com/aelitis/azureus/ui/images/grey_bubble.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/ic_thumbs.png b/com/aelitis/azureus/ui/images/ic_thumbs.png
deleted file mode 100644
index 58f7832..0000000
Binary files a/com/aelitis/azureus/ui/images/ic_thumbs.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/ic_thumbsDown.png b/com/aelitis/azureus/ui/images/ic_thumbsDown.png
deleted file mode 100644
index 94e65fe..0000000
Binary files a/com/aelitis/azureus/ui/images/ic_thumbsDown.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/ic_thumbsUp.png b/com/aelitis/azureus/ui/images/ic_thumbsUp.png
deleted file mode 100644
index 963f9b9..0000000
Binary files a/com/aelitis/azureus/ui/images/ic_thumbsUp.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/large_red_bubble.png b/com/aelitis/azureus/ui/images/large_red_bubble.png
deleted file mode 100644
index 9f36ceb..0000000
Binary files a/com/aelitis/azureus/ui/images/large_red_bubble.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/no_friends.png b/com/aelitis/azureus/ui/images/no_friends.png
deleted file mode 100644
index bb298ce..0000000
Binary files a/com/aelitis/azureus/ui/images/no_friends.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/rateme.png b/com/aelitis/azureus/ui/images/rateme.png
deleted file mode 100644
index ed4b87c..0000000
Binary files a/com/aelitis/azureus/ui/images/rateme.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/rateme_button-disabled.png b/com/aelitis/azureus/ui/images/rateme_button-disabled.png
deleted file mode 100644
index 36b2a86..0000000
Binary files a/com/aelitis/azureus/ui/images/rateme_button-disabled.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/rateme_button.png b/com/aelitis/azureus/ui/images/rateme_button.png
deleted file mode 100644
index bfa44cb..0000000
Binary files a/com/aelitis/azureus/ui/images/rateme_button.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/rateme_down.png b/com/aelitis/azureus/ui/images/rateme_down.png
deleted file mode 100644
index a884398..0000000
Binary files a/com/aelitis/azureus/ui/images/rateme_down.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/rateme_up.png b/com/aelitis/azureus/ui/images/rateme_up.png
deleted file mode 100644
index c68f990..0000000
Binary files a/com/aelitis/azureus/ui/images/rateme_up.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/red_bubble.png b/com/aelitis/azureus/ui/images/red_bubble.png
deleted file mode 100644
index 33943c2..0000000
Binary files a/com/aelitis/azureus/ui/images/red_bubble.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-od-bel.png b/com/aelitis/azureus/ui/images/sb/20px-od-bel.png
new file mode 100644
index 0000000..b582db7
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-od-bel.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-od-other.png b/com/aelitis/azureus/ui/images/sb/20px-od-other.png
new file mode 100644
index 0000000..7bb2dc7
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-od-other.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-od-vuze.png b/com/aelitis/azureus/ui/images/sb/20px-od-vuze.png
new file mode 100644
index 0000000..0a45310
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-od-vuze.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/friends_bg.png b/com/aelitis/azureus/ui/images/sb/friends_bg.png
deleted file mode 100644
index 58dd244..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/friends_bg.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_device_od.png b/com/aelitis/azureus/ui/images/sb/ic_device_od.png
new file mode 100644
index 0000000..0e030c3
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/ic_device_od.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_rcm.png b/com/aelitis/azureus/ui/images/sb/ic_rcm.png
new file mode 100644
index 0000000..a4514f8
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/ic_rcm.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/icon_hide_notch.png b/com/aelitis/azureus/ui/images/sb/icon_hide_notch.png
deleted file mode 100644
index 55bfaf3..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/icon_hide_notch.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/icon_hide_notch_over.png b/com/aelitis/azureus/ui/images/sb/icon_hide_notch_over.png
deleted file mode 100644
index e275950..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/icon_hide_notch_over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/icon_show_notch.png b/com/aelitis/azureus/ui/images/sb/icon_show_notch.png
deleted file mode 100644
index f334ba2..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/icon_show_notch.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/icon_show_notch_over.png b/com/aelitis/azureus/ui/images/sb/icon_show_notch_over.png
deleted file mode 100644
index a234614..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/icon_show_notch_over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/account_bdr_lft.png b/com/aelitis/azureus/ui/images/tb/account_bdr_lft.png
deleted file mode 100644
index 5e1d9da..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/account_bdr_lft.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/account_bdr_lft_small.png b/com/aelitis/azureus/ui/images/tb/account_bdr_lft_small.png
deleted file mode 100644
index fea98d8..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/account_bdr_lft_small.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/account_bdr_mid.png b/com/aelitis/azureus/ui/images/tb/account_bdr_mid.png
deleted file mode 100644
index 3f1e16c..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/account_bdr_mid.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/account_bdr_mid_small.png b/com/aelitis/azureus/ui/images/tb/account_bdr_mid_small.png
deleted file mode 100644
index 919c68e..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/account_bdr_mid_small.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/account_bdr_rgt.png b/com/aelitis/azureus/ui/images/tb/account_bdr_rgt.png
deleted file mode 100644
index a688660..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/account_bdr_rgt.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/account_bdr_rgt_small.png b/com/aelitis/azureus/ui/images/tb/account_bdr_rgt_small.png
deleted file mode 100644
index d42fd9e..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/account_bdr_rgt_small.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_share.png b/com/aelitis/azureus/ui/images/tb/ic_share.png
deleted file mode 100644
index bc57d93..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_share.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_share_disabled.png b/com/aelitis/azureus/ui/images/tb/ic_share_disabled.png
deleted file mode 100644
index d53ab0d..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_share_disabled.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/thumb_down.png b/com/aelitis/azureus/ui/images/thumb_down.png
deleted file mode 100644
index 2906a47..0000000
Binary files a/com/aelitis/azureus/ui/images/thumb_down.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/thumb_down_small.png b/com/aelitis/azureus/ui/images/thumb_down_small.png
deleted file mode 100644
index 7b21eb6..0000000
Binary files a/com/aelitis/azureus/ui/images/thumb_down_small.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/thumb_up.png b/com/aelitis/azureus/ui/images/thumb_up.png
deleted file mode 100644
index bf1e314..0000000
Binary files a/com/aelitis/azureus/ui/images/thumb_up.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/thumb_up_small.png b/com/aelitis/azureus/ui/images/thumb_up_small.png
deleted file mode 100644
index ada57ca..0000000
Binary files a/com/aelitis/azureus/ui/images/thumb_up_small.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/skin/SkinConstants.java b/com/aelitis/azureus/ui/skin/SkinConstants.java
index aba6898..f885030 100644
--- a/com/aelitis/azureus/ui/skin/SkinConstants.java
+++ b/com/aelitis/azureus/ui/skin/SkinConstants.java
@@ -33,12 +33,6 @@ public class SkinConstants
 
 	public static final String VIEWID_BROWSER_SEARCHRESULTS = "searchresults";
 
-	public static final String VIEWID_BROWSER_MINI = "minibrowse";
-
-	public static final String VIEWID_BROWSER_PUBLISH = "publish";
-
-	public static final String VIEWID_BUDDIES_VIEWER = "buddies-viewer";
-
 	public static final String VIEWID_PLUGINBAR = "pluginbar";
 
 	public static final String VIEWID_TAB_BAR = "tabbar";
@@ -63,8 +57,6 @@ public class SkinConstants
 
 	public static final String VIEWID_SIDEBAR = "sidebar";
 
-	public static final String VIEWID_FRIENDS_TOOLBAR = "toolbar-friends";
-	
 	public static final String VIEWID_LIBRARY_TOOLBAR = "library-list-button-smalltable";
 	public static final String VIEWID_LIBRARY_TOOLBAR_BIG = "library-list-button-bigtable";
 
diff --git a/com/aelitis/azureus/ui/skin/SkinPropertiesImpl.java b/com/aelitis/azureus/ui/skin/SkinPropertiesImpl.java
index 13e2b0f..90e62f9 100644
--- a/com/aelitis/azureus/ui/skin/SkinPropertiesImpl.java
+++ b/com/aelitis/azureus/ui/skin/SkinPropertiesImpl.java
@@ -80,7 +80,7 @@ public class SkinPropertiesImpl
 		}
 		ResourceBundle bundle = ResourceBundle.getBundle(skinPath + mainSkinFile,
 				Locale.getDefault(), classLoader);
-		rb = new IntegratedResourceBundle(bundle, Collections.EMPTY_MAP);
+		rb = new IntegratedResourceBundle(bundle, Collections.EMPTY_MAP, 1200);
 		rb.setUseNullList(true);
 
 		String sFiles = rb.getString("skin.include", null);
diff --git a/com/aelitis/azureus/ui/skin/skin3.properties b/com/aelitis/azureus/ui/skin/skin3.properties
index c2e1d4b..87c7e7a 100644
--- a/com/aelitis/azureus/ui/skin/skin3.properties
+++ b/com/aelitis/azureus/ui/skin/skin3.properties
@@ -7,10 +7,9 @@ skin.include=skin3_topbar,\
              skin3_tab_browse,\
              skin3_tab_searchresults,\
              skin3_constants,\
-             skin3_buddies_viewer,\
              skin3_sbc_library,\
-             skin3_sidebar_friends,\
              skin3_devices,\
+             skin3_devices_od,\
              skin3_rcm
 
 main.shell.widgets=main.shell.area
diff --git a/com/aelitis/azureus/ui/skin/skin3_activities.properties b/com/aelitis/azureus/ui/skin/skin3_activities.properties
index ad9d395..1450184 100644
--- a/com/aelitis/azureus/ui/skin/skin3_activities.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_activities.properties
@@ -1,72 +1,3 @@
-#events area
-main.area.events.type=container
-main.area.events.view=vuzeevents-area
-main.area.events.widgets=main.events.top,main.events.data
-main.area.events.attach.template=template.fill
-main.area.events.color={color.table.bg}
-
-main.events.top.type=container
-main.events.top.widgets=events.sortby.title,\
-                        events.sortby.date,\
-                        events.sortby.category,\
-                        events.button.readall
-main.events.top.attach.top=0,0
-main.events.top.attach.right=100,0
-main.events.top.attach.left=0,0
-
-events.sortby.title.type=text,Sort By:
-events.sortby.title.height=21
-#events.sortby.title.text.style=bold
-events.sortby.title.text.v-padding=8
-events.sortby.title.attach.left=0,10
-events.sortby.title.v-align=center
-
-events.sortby.date.type=text,Date
-events.sortby.date.view=vuzeevents-sortby-date
-events.sortby.date.color.style-selected=rounded-fill
-events.sortby.date.text.style-selected=bold
-events.sortby.date.text.style=normal
-events.sortby.date.text.h-padding=6
-events.sortby.date.text.v-padding=4
-events.sortby.date.align=center
-events.sortby.date.v-align=center
-events.sortby.date.attach.left=events.sortby.title,10
-events.sortby.date.attach.top=events.sortby.title,center
-events.sortby.date.cursor=hand
-
-events.sortby.category.type=text,Type
-events.sortby.category.view=vuzeevents-sortby-type
-events.sortby.category.color.style-selected=rounded-fill
-events.sortby.category.text.style-selected=bold
-events.sortby.category.text.style=normal
-events.sortby.category.text.h-padding=6
-events.sortby.category.text.v-padding=4
-events.sortby.category.align=center
-events.sortby.category.v-align=center
-events.sortby.category.attach.left=events.sortby.date,10
-events.sortby.category.attach.top=events.sortby.title,center
-events.sortby.category.cursor=hand
-
-events.button.readall.type=button
-events.button.readall.text={v3.activity.button.readall}
-events.button.readall.view=vuzeevents-button-readall
-events.button.readall.attach.right=100,0
-events.button.readall.attach.left=
-
-main.events.data.type=container
-main.events.data.border=1
-main.events.data.view=vuzeevents-list
-main.events.data.color={color.table.bg}
-main.events.data.attach.top=main.events.top,0
-main.events.data.attach.bottom=100,0
-main.events.data.attach.left=0,0
-main.events.data.attach.right=100,0
-
-
-#####################
-######################
-#####################
-
 activity.type=container
 activity.view=sidebar-activity-area
 activity.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.SBC_ActivityView
diff --git a/com/aelitis/azureus/ui/skin/skin3_buddies_viewer.properties b/com/aelitis/azureus/ui/skin/skin3_buddies_viewer.properties
deleted file mode 100644
index 3636fcb..0000000
--- a/com/aelitis/azureus/ui/skin/skin3_buddies_viewer.properties
+++ /dev/null
@@ -1,57 +0,0 @@
-#===============================================================================
-# buddies.viewer
-#(The the buddies area in the left nav)
-#===============================================================================
-
-buddies.viewer.type=container
-buddies.viewer.view=buddies-viewer
-buddies.viewer.attach.top=friends.toolbar,0
-buddies.viewer.attach.left=0,0
-buddies.viewer.attach.right=100,0
-buddies.viewer.attach.bottom=100,0
-buddies.viewer.widgets=nobuddies.panel
-buddies.viewer.color={color.sidebar.bg}
-
-nobuddies.panel.type=container
-nobuddies.panel.visible=0
-nobuddies.panel.view=buddies-viewer-nobuddies-panel
-nobuddies.panel.attach.template=template.fill
-nobuddies.panel.widgets=nobuddies,\
-						nobuddies.message,\
-						nobuddies.faq
-						
-nobuddies.type=image,{image.buddies.nobuddy}
-nobuddies.view=buddies-viewer-nobuddies-graphic
-nobuddies.cursor=hand
-nobuddies.attach.left=0,10
-nobuddies.attach.top=0,35
-
-nobuddies.message.type=text
-nobuddies.message.text={message.intro.friends}
-nobuddies.message.view=buddies-viewer-nobuddies-message
-nobuddies.message.text.style=shadow
-nobuddies.message.text.color=#6D6F6E
-nobuddies.message.text.size=15px
-nobuddies.message.antialias=1
-nobuddies.message.text.style=normal
-nobuddies.message.align=left
-nobuddies.message.attach.left=0,75
-nobuddies.message.attach.top=0,45
-
-nobuddies.faq.type=text
-nobuddies.faq.text={v3.buddies.faq}
-nobuddies.faq.view=buddies-viewer-nobuddies-link
-nobuddies.faq.text.style-selected=allcaps
-nobuddies.faq.text.style=allcaps,shadow
-nobuddies.faq.text.size=12px
-nobuddies.faq.antialias=1
-nobuddies.faq.text.color={color.links.normal}
-nobuddies.faq.text.color-over={color.links.hover}
-nobuddies.faq.text.style=normal
-nobuddies.faq.align=left
-nobuddies.faq.cursor=hand
-nobuddies.faq.attach.left=nobuddies.message,left,0
-nobuddies.faq.attach.top=nobuddies.message,0
-
-
-
diff --git a/com/aelitis/azureus/ui/skin/skin3_constants.properties b/com/aelitis/azureus/ui/skin/skin3_constants.properties
index 2703b6c..2b623bd 100644
--- a/com/aelitis/azureus/ui/skin/skin3_constants.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_constants.properties
@@ -21,12 +21,6 @@ template.tabcontentarea.attach.bottom=100,-{template.padding}
 template.tabcontentarea.attach.left=0,{template.padding}
 template.tabcontentarea.attach.right=100,-{template.padding}
 
-template.grayline.type=image
-template.grayline.image={template.imagedir}/grayhline.png
-template.grayline.drawmode=tile
-template.grayline.attach.left=0,0
-template.grayline.attach.right=100,0
-
 #colors
 #===============================================================================
 
@@ -102,16 +96,6 @@ table.Activity.color.row.odd.fg=COLOR_LIST_TEXT
 table.Activity.color.row.odd.selected.fg=COLOR_WIDGET_FOREGROUND
 table.Activity.color.row.odd.selected.bg=COLOR_WIDGET_BACKGROUND
 
-color.buddy.foreground.add.all=#B6DDB6
-color.buddy.foreground.add.all.hover=#F6DDF6
-color.buddy.foreground.add.all.disabled=#555555
-color.buddy.filedrag.bg.border=130,130,130
-color.buddy.filedrag.bg=0,73,153
-color.buddy.bg.border=55,55,55
-color.buddy.bg.selected=16,16,16
-color.buddy.bg.hover=45,45,45
-
-
 color.vuze-entry.news.bg=#252932
 color.vuze-entry.news.fg=#FFFFFF
 
@@ -144,16 +128,6 @@ color.search.text.fg=#333333
 color.search.text.fg.default=#999999
 
 #===============================================================================
-#main.area.publishtab
-#===============================================================================
-
-publishtab.area.type=browser
-publishtab.area.view=publish
-publishtab.area.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.Publish
-publishtab.area.color={color.view.background}
-publishtab.area.attach.template=template.fill
-
-#===============================================================================
 #main.area.advancedtab
 #===============================================================================
 
@@ -193,23 +167,6 @@ main.area.statusbar.attach.right=100,0
 
 column.azproduct.product={template.imagedir}/icon-AzureusProduct-24x24.png
 column.azproduct.globe={template.imagedir}/icon-Globe-24x24.png
-icon.quality.HD={template.imagedir}/qual_hd.png
-icon.quality.SD={template.imagedir}/qual_sd.png
-
-icon.rateme={template.imagedir}/rateme.png
-icon.rateme.up={template.imagedir}/rateme_up.png
-icon.rateme.down={template.imagedir}/rateme_down.png
-icon.rateme-button={template.imagedir}/rateme_button.png
-icon.rateme-button-disabled={template.imagedir}/rateme_button-disabled.png
-icon.rate.up={template.imagedir}/thumb_up.png
-icon.rate.down={template.imagedir}/thumb_down.png
-icon.rate.small.up={template.imagedir}/thumb_up_small.png
-icon.rate.small.down={template.imagedir}/thumb_down_small.png
-icon.rate.wait={template.imagedir}/clock_wait.png
-
-icon.rate.library={template.imagedir}/ic_thumbs.png
-icon.rate.library.up={template.imagedir}/ic_thumbsUp.png
-icon.rate.library.down={template.imagedir}/ic_thumbsDown.png
 
 icon.editpencil={template.imagedir}/icon-pencil-14x15.png
 
@@ -229,34 +186,14 @@ image.button.download={template.imagedir}/tb/download.png
 image.button.share={template.imagedir}/tb/ic_share.png
 image.button.transcode={template.imagedir}/tb/ic_device.png
 
-image.bottom.bar={template.imagedir}/bottom_bar_bg.gif
-
 image.vuze-entry.comments={template.imagedir}/entry_comments.png
 image.vuze-entry.featured={template.imagedir}/entry_featured.png
 image.vuze-entry.news={template.imagedir}/entry_news.png
-image.vuze-entry.rating-reminder={template.imagedir}/entry_thumbsup.png
-image.vuze-entry.buddy-request={template.imagedir}/entry_buddy_req.png
-image.vuze-entry.buddy-invited={template.imagedir}/entry_buddy_req.png
-image.vuze-entry.buddy-new={template.imagedir}/entry_buddy_new.png
-image.vuze-entry.buddy-share={template.imagedir}/entry_buddy_share.png
 image.vuze-entry.frog={template.imagedir}/entry_frog.png
 
 image.help={template.imagedir}/help.png
 image.separator={template.imagedir}/separator.gif
 
-image.big.scroll.left={template.imagedir}/button_left_scroll.png
-image.big.scroll.right={template.imagedir}/button_right_scroll.png
-
-image.buddies.nobuddy={template.imagedir}/no_friends.png
-
-image.buddy.default.avatar={template.imagedir}/buddy_default_avatar.png
-image.buddy.add.to.share={template.imagedir}/buddy_add_to_share.png
-image.buddy.add.to.share-selected={template.imagedir}/buddy_add_to_share_selected.png
-image.buddy.add.to.share-over={template.imagedir}/buddy_add_to_share-over.png
-image.buddy.remove={template.imagedir}/buddy_remove.png
-image.buddy.remove-over={template.imagedir}/buddy_remove-over.png
-image.buddy.add={template.imagedir}/buddy_add.png
-
 image.searchbox={template.imagedir}/tb/search_bg_lft.png,{template.imagedir}/tb/search_bg_mid.png,{template.imagedir}/tb/search_bg_rgt.png
 image.searchbox.middle={template.imagedir}/tb/search_bg_mid.png
 image.search.dropdown={template.imagedir}/tb/search_btn.png
@@ -297,6 +234,7 @@ image.sidebar.dropdown={template.imagedir}/sb_menu.png
 image.sidebar.activity={template.imagedir}/sb/ic_activity.png
 image.sidebar.vuze={template.imagedir}/sb/ic_vuze.png
 image.sidebar.subscriptions={template.imagedir}/sb/ic_rss.png
+image.sidebar.rcm={template.imagedir}/sb/ic_rcm.png
 image.sidebar.welcome={template.imagedir}/sb/ic_welcome.png
 image.sidebar.library={template.imagedir}/sb/ic_library.png
 image.sidebar.search={template.imagedir}/sb/ic_search.png
@@ -315,6 +253,7 @@ image.sidebar.devices={template.imagedir}/sb/ic_device.png
 image.sidebar.device.renderer={template.imagedir}/sb/ic_device_rend.png
 image.sidebar.device.mediaserver={template.imagedir}/sb/ic_device_ms.png
 image.sidebar.device.router={template.imagedir}/sb/ic_device_rout.png
+image.sidebar.device.offlinedownloader={template.imagedir}/sb/ic_device_od.png
 image.sidebar.device.internet={template.imagedir}/sb/ic_device_int.png
 image.sidebar.device.2.big={template.imagedir}/30px-xbox.png
 image.sidebar.device.2.small={template.imagedir}/sb/20px-xbox.png
@@ -327,12 +266,14 @@ image.sidebar.device.5.small={template.imagedir}/sb/20px-other.png
 image.sidebar.device.6.small={template.imagedir}/sb/20px-other.png
 image.sidebar.device.psp.small={template.imagedir}/sb/20px-psp.png
 image.sidebar.device.tivo.small={template.imagedir}/sb/20px-tivo.png
+image.sidebar.device.od.bel.small={template.imagedir}/sb/20px-od-bel.png
+image.sidebar.device.od.vuze.small={template.imagedir}/sb/20px-od-vuze.png
+image.sidebar.device.od.other.small={template.imagedir}/sb/20px-od-other.png
 
 image.sidebar.turnon={template.imagedir}/sb/btn-turnon.png
 image.sidebar.beta={template.imagedir}/sb/beta.png
 
-image.account.bg={template.imagedir}/tb/account_bdr_lft.png,{template.imagedir}/tb/account_bdr_mid.png,{template.imagedir}/tb/account_bdr_rgt.png
-image.saccount.bg={template.imagedir}/tb/account_bdr_lft_small.png,{template.imagedir}/tb/account_bdr_mid_small.png,{template.imagedir}/tb/account_bdr_rgt_small.png
+image.device.logo.belkin={template.imagedir}/device_bel_logo.png
 
 image.activity.unread={template.imagedir}/new_dot.png
 image.unopened={template.imagedir}/new_dot.png
@@ -341,7 +282,6 @@ image.opened={template.imagedir}/old_dot.png
 
 image.trash={template.imagedir}/icon_trash_matte.png
 
-icon.info={template.imagedir}/btn_details.png
 image.dismissX={template.imagedir}/dismissX.gif
 
 ic_view={template.imagedir}/ic_view.png
@@ -359,36 +299,6 @@ icon_rss=com/aelitis/azureus/ui/images/icon_rss.png
 ranking_bars=com/aelitis/azureus/ui/images/ranking_bars.png
 wizard_header_bg=com/aelitis/azureus/ui/images/wizard_header_bg.png
 
-buddy_prompt_image=com/aelitis/azureus/ui/images/buddy_prompt_image.png
-
-btn_collapse=com/aelitis/azureus/ui/images/sb/icon_hide_notch.png
-btn_collapse_over=com/aelitis/azureus/ui/images/sb/icon_hide_notch_over.png
-btn_expand=com/aelitis/azureus/ui/images/sb/icon_show_notch.png
-btn_expand_over=com/aelitis/azureus/ui/images/sb/icon_show_notch_over.png
-friends_bg=com/aelitis/azureus/ui/images/sb/friends_bg.png
-add_to_share=com/aelitis/azureus/ui/images/buddy_add_to_share.png
-add_to_share_selected=com/aelitis/azureus/ui/images/buddy_add_to_share_selected.png
-
-button_skin_close=com/aelitis/azureus/ui/images/button_skin_close.png
-button_skin_close-over=com/aelitis/azureus/ui/images/button_skin_close-over.png
-
-button_dialog_min=com/aelitis/azureus/ui/images/button_dialog_min.png
-button_dialog_min-over=com/aelitis/azureus/ui/images/button_dialog_min-over.png
-
-button_dialog_left=com/aelitis/azureus/ui/images/button_dialog_left.png
-button_dialog_center=com/aelitis/azureus/ui/images/button_dialog_center.png
-button_dialog_right=com/aelitis/azureus/ui/images/button_dialog_right.png
-button_dialog_left-over=com/aelitis/azureus/ui/images/button_dialog_left-over.png
-button_dialog_center-over=com/aelitis/azureus/ui/images/button_dialog_center-over.png
-button_dialog_right-over=com/aelitis/azureus/ui/images/button_dialog_right-over.png
-
-chatNotification=com/aelitis/azureus/ui/images/chatNotification.png
-
-friend_online_icon=com/aelitis/azureus/ui/images/friend_online_icon.png
-grey_bubble=com/aelitis/azureus/ui/images/grey_bubble.png
-red_bubble=com/aelitis/azureus/ui/images/red_bubble.png
-large_red_bubble=com/aelitis/azureus/ui/images/large_red_bubble.png
-
 tc_bar_end=com/aelitis/azureus/ui/images/tc_bar_end.png
 tc_bar_0=com/aelitis/azureus/ui/images/tc_bar_0.png
 tc_bar_1=com/aelitis/azureus/ui/images/tc_bar_1.png
@@ -411,9 +321,6 @@ table.library-small.row.margin.height=2
 #==================
 UnattachedView.advanced=main.area.advancedtab,sidebar.middle
 UnattachedView.browse=main.area.browse,main.area.middle
-UnattachedView.publish=main.area.publishtab,main.area.middle
 
 ###
 sidebar.defaultwidth=205
-profile.defaultwidth=185
-profile.indent=5
diff --git a/com/aelitis/azureus/ui/skin/skin3_devices_od.properties b/com/aelitis/azureus/ui/skin/skin3_devices_od.properties
new file mode 100644
index 0000000..dee771b
--- /dev/null
+++ b/com/aelitis/azureus/ui/skin/skin3_devices_od.properties
@@ -0,0 +1,23 @@
+devicesodview.type=container
+devicesodview.onshow.skinviewclass=com.aelitis.azureus.ui.swt.devices.SBC_DevicesODView
+devicesodview.widgets=\
+	devicesodview.title,\
+	devicesodview.list
+devicesodview.attach.template=template.fill
+
+devicesodview.title.type=text,{devices.od.view.heading}
+devicesodview.title.text.v-padding=10
+devicesodview.title.text.h-padding=5
+devicesodview.title.view=title
+devicesodview.title.attach.template=template.fill
+devicesodview.title.attach.bottom=
+devicesodview.title.attach.right=
+devicesodview.title.text.size=15px
+devicesodview.title.text.style=bold
+
+devicesodview.list.type=container
+devicesodview.list.attach.template=template.fill
+devicesodview.list.attach.top=devicesodview.title,0
+devicesodview.list.view=devicesod-list
+
+##
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/skin/skin3_dlg_coreloading.properties b/com/aelitis/azureus/ui/skin/skin3_dlg_coreloading.properties
index 1c0d045..44ba487 100644
--- a/com/aelitis/azureus/ui/skin/skin3_dlg_coreloading.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_dlg_coreloading.properties
@@ -16,8 +16,7 @@ coreloading.main.widgets=coreloading.logo,\
 		coreloading.info,\
 		coreloading.task,\
 		coreloading.progress
-coreloading.main.color=#f0f0f0
-coreloading.main.color.style=gradient,#b1adae
+coreloading.main.color=#f3fbff
 
 coreloading.logo.type=image,{image.logo}
 coreloading.logo.width=95
@@ -37,15 +36,15 @@ coreloading.progress.color=#a0a0a0
 coreloading.task.type=text
 coreloading.task.view=task
 coreloading.task.text.size=10px
-coreloading.task.text.color=#808080
+coreloading.task.text.color=#999999
 coreloading.task.attach.top=coreloading.progress,2
 coreloading.task.attach.left=coreloading.info,-5,left
 coreloading.task.attach.right=100,-20
 coreloading.task.attach.bottom=100,-2
 
 coreloading.info.type=text,{dlg.corewait.text}  
-coreloading.info.text.size=17px
-coreloading.info.text.color=#2459ab
+coreloading.info.text.size=14px
+coreloading.info.text.color=#1c5682
 coreloading.info.attach.top=coreloading.logo,5,top
 coreloading.info.attach.left=coreloading.logo,12
 coreloading.info.attach.right=100,-15
diff --git a/com/aelitis/azureus/ui/skin/skin3_maintabs.properties b/com/aelitis/azureus/ui/skin/skin3_maintabs.properties
index 9f25d1d..ee5cd5b 100644
--- a/com/aelitis/azureus/ui/skin/skin3_maintabs.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_maintabs.properties
@@ -20,7 +20,6 @@ main.area.maintabs.widgets=main.area.topgap,\
 	                         maintabs.area.search,\
 	                         maintabs.line,\
                            maintabs.vcenter,\
-                           user.info,\
                            maintabs.area.sidebarpop
                            
 main.area.maintabs.view=tabbar
@@ -130,10 +129,10 @@ maintabs.area.search.propogate=1
 maintabs.area.search.widgets=widget.search-button1,\
 	                           widget.search-area,\
 	                           widget.search-line
-maintabs.area.search.attach.left=user.info,14
+maintabs.area.search.attach.left=0,5
 maintabs.area.search.attach.top=main.area.topgap,0
 maintabs.area.search.attach.bottom=100,0
-maintabs.area.search.width=260
+maintabs.area.search.width=200
 
 widget.search-line.type=container
 widget.search-line.height=1
@@ -170,80 +169,11 @@ widget.search-button1.attach.left=0,0
 widget.search-button1.attach.top=widget.search-area,0,top
 widget.search-button1.attach.bottom=widget.search-area,0,bottom
 
-
-widget.search-button2.type=clone,toolbar.area.item.title
-widget.search-button2.text=Search
-widget.search-button2.view=search-go
-widget.search-button2.attach.right=100,0
-widget.search-button2.attach.left=0,2
-widget.search-button2.attach.bottom=widget.search-line,-1
-widget.search-button2.tooltip={v3.MainWindow.search.go.tooltip}
-widget.search-button2.cursor=hand
-
-
-##########
-user.info.type=container
-user.info.view=user-info
-user.info.attach.left=0,{profile.indent}
-user.info.attach.top=main.area.topgap,3
-user.info.width={profile.defaultwidth}
-user.info.widgets=user.info.text_clickable,\
-                  user.info.image_dropdown_clickable,\
-                  user.info.image_profile
-user.info.color=COLOR_LIST_BACKGROUND
-user.info.background={image.account.bg}
-user.info.background-small={image.saccount.bg}
-user.info.background.drawmode=tile-x
-#user.info.visible=false
-
-user.info.text_clickable.type=text
-user.info.text_clickable.view=user-info-name
-user.info.text_clickable.fgcolor=#323942
-user.info.text_clickable.fgcolor-over=#000000
-user.info.text_clickable.align=left
-user.info.text_clickable.attach.left=user.info.image_dropdown_clickable,0
-user.info.text_clickable.attach.right=100,-4
-user.info.text_clickable.attach.top=0,1
-user.info.text_clickable.attach.bottom=100,0
-user.info.text_clickable.cursor=hand
-user.info.text_clickable.text.size=13px
-user.info.text_clickable.text.size._mac=14px
-#user.info.text_clickable.text.style=bold
-user.info.text_clickable.v-align=top
-
-user.info.image_dropdown_clickable.type=container
-user.info.image_dropdown_clickable.view=user-info-image
-user.info.image_dropdown_clickable.attach.left=user.info.image_profile,0
-user.info.image_dropdown_clickable.attach.top=0,2
-user.info.image_dropdown_clickable.attach.bottom=100,-2
-user.info.image_dropdown_clickable.width=14
-user.info.image_dropdown_clickable.cursor=hand
-user.info.image_dropdown_clickable.widgets=user.info.image_dropdown,\
-
-user.info.image_dropdown.type=image
-user.info.image_dropdown.image={image.bullet.arrow.down}
-user.info.image_dropdown.drawmode=h-center
-user.info.image_dropdown.attach.left=0,0
-user.info.image_dropdown.attach.top=0,2
-user.info.image_dropdown.attach.right=100,0
-user.info.image_dropdown.attach.bottom=100,0
-user.info.image_dropdown.cursor=hand
-
-
-user.info.image_profile.type=image
-user.info.image_profile.drawmode=stretch
-user.info.image_profile.view=user-info-profile-image
-user.info.image_profile.image={image.buddy.default.avatar}
-user.info.image_profile.attach.left=0,4
-user.info.image_profile.attach.top=0,2
-user.info.image_profile.attach.bottom=100,-2
-user.info.image_profile.width=26
-
 ##########
 
 toolbar.area.item.type=container
 toolbar.area.item.widgets=toolbar.area.item.image,toolbar.area.item.title
-toolbar.area.item.attach.0,1
+toolbar.area.item.attach.top=0,1
 toolbar.area.item.cursor=hand
 #toolbar.area.item.debug=1
 
@@ -267,6 +197,7 @@ toolbar.area.item.title.attach.bottom=100,0
 toolbar.area.item.title.attach.top=
 toolbar.area.item.title.align=center
 toolbar.area.item.title.text.font=verdana
+toolbar.area.item.title.text.font._mac=
 toolbar.area.item.title.text.size=11px
 toolbar.area.item.title.fgcolor=#333333
 toolbar.area.item.title.fgcolor-disabled=#808080
@@ -313,6 +244,7 @@ toolbar.area.sitem.title.attach.bottom=100,0
 toolbar.area.sitem.title.attach.top=
 toolbar.area.sitem.title.align=center
 toolbar.area.sitem.title.text.font=verdana
+toolbar.area.sitem.title.text.font._mac=
 toolbar.area.sitem.title.text.size=11px
 toolbar.area.sitem.title.text.h-padding=2
 toolbar.area.sitem.title.fgcolor=#333333
@@ -403,13 +335,14 @@ toolbar.area.vitem.title.attach.bottom=100,0
 toolbar.area.vitem.title.attach.top=
 toolbar.area.vitem.title.align=center
 toolbar.area.vitem.title.text.font=verdana
+toolbar.area.vitem.title.text.font._mac=
 toolbar.area.vitem.title.text.size=11px
 toolbar.area.vitem.title.fgcolor=#333333
 toolbar.area.vitem.title.fgcolor-disabled=#808080
 
 ###
 
-toolbar.area.sitem.left2.type=image
+toolbar.area.sitem.left2.type=container
 toolbar.area.sitem.left2.attach.top=0,1
 toolbar.area.sitem.left2.attach.left=0,18
 
diff --git a/com/aelitis/azureus/ui/skin/skin3_rcm.properties b/com/aelitis/azureus/ui/skin/skin3_rcm.properties
index 5cc5960..b7e4ebb 100644
--- a/com/aelitis/azureus/ui/skin/skin3_rcm.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_rcm.properties
@@ -1,23 +1,46 @@
 rcmview.type=container
 rcmview.onshow.skinviewclass=com.aelitis.azureus.ui.swt.content.SBC_RCMView
 rcmview.widgets=\
-	rcmview.title,\
+	rcmview.toparea,\
 	rcmview.list
 rcmview.attach.template=template.fill
 
+rcmview.toparea.type=container
+rcmview.toparea.widgets=\
+	rcmview.title,\
+	rcmview.filterarea,\
+	rcmview.sizeslider
+rcmview.toparea.attach.template=template.fill
+rcmview.toparea.attach.bottom=
+rcmview.toparea.height=30
+
+
 rcmview.title.type=text,{rcm.view.heading}
-rcmview.title.text.v-padding=10
-rcmview.title.text.h-padding=5
 rcmview.title.view=title
 rcmview.title.attach.template=template.fill
-rcmview.title.attach.bottom=
 rcmview.title.attach.right=
+rcmview.title.attach.left=0,5
+rcmview.title.v-align=center
 rcmview.title.text.size=15px
 rcmview.title.text.style=bold
 
+rcmview.filterarea.type=container
+rcmview.filterarea.view=filterarea
+rcmview.filterarea.attach.template=template.fill
+rcmview.filterarea.attach.left=rcmview.title,10
+rcmview.filterarea.attach.right=rcmview.sizeslider,-5
+rcmview.filterarea.height=30
+
+rcmview.sizeslider.type=container
+rcmview.sizeslider.view=table-size-slider
+rcmview.sizeslider.attach.right=100,-5
+rcmview.sizeslider.attach.top=0,0
+rcmview.sizeslider.attach.bottom=100,0
+rcmview.sizeslider.width=75
+
 rcmview.list.type=container
 rcmview.list.attach.template=template.fill
-rcmview.list.attach.top=rcmview.title,0
+rcmview.list.attach.top=rcmview.toparea,0
 rcmview.list.view=rcm-list
 
 ##
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/skin/skin3_sbc_library.properties b/com/aelitis/azureus/ui/skin/skin3_sbc_library.properties
index 6a09a83..29a5ad9 100644
--- a/com/aelitis/azureus/ui/skin/skin3_sbc_library.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_sbc_library.properties
@@ -87,8 +87,7 @@ library.wait.visible=0
 library.wait.view=library-wait
 library.wait.attach.template=template.fill
 library.wait.widgets=library.wait.icon,library.wait.task,library.wait.progress,library.wait.text
-library.wait.color=#f0f0f0
-library.wait.color.style=gradient,#f0f0f0,0.2,#4f4e4a,1
+library.wait.color=#f3fbff
 
 library.wait.icon.type=image,{image.logo}
 library.wait.icon.align=center
@@ -98,7 +97,7 @@ library.wait.icon.attach.left=50,-75
 library.wait.task.type=text
 library.wait.task.view=library-wait-task
 library.wait.task.text.size=10px
-library.wait.task.text.color=#808080
+library.wait.task.text.color=#999999
 library.wait.task.width=300
 library.wait.task.attach.left=50,-150
 library.wait.task.attach.top=library.wait.icon,20
@@ -106,15 +105,16 @@ library.wait.task.attach.top=library.wait.icon,20
 library.wait.progress.type=container
 library.wait.progress.view=library-wait-progress
 library.wait.progress.attach.top=library.wait.task,2
-library.wait.progress.height=2
+library.wait.progress.height=4
 library.wait.progress.width=300
 library.wait.progress.attach.left=50,-150
-library.wait.progress.color=#808080
+library.wait.progress.color=#666666
 
-library.wait.text.type=text,{library.core.wait}
-library.wait.text.text.size=23px
-library.wait.text.text.color=#2459ab
+library.wait.text.type=text,Loading
+library.wait.text.align=center
+library.wait.text.text.size=17px
+library.wait.text.text.color=#1c5682
 library.wait.text.width=300
 library.wait.text.attach.left=50,-150
-library.wait.text.attach.top=library.wait.progress,20
+library.wait.text.attach.top=library.wait.progress,10
 
diff --git a/com/aelitis/azureus/ui/skin/skin3_sidebar.properties b/com/aelitis/azureus/ui/skin/skin3_sidebar.properties
index fe569aa..8829411 100644
--- a/com/aelitis/azureus/ui/skin/skin3_sidebar.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_sidebar.properties
@@ -35,36 +35,17 @@ main.sidebar.attach.top=0,0
 main.sidebar.attach.bottom=100,0
 main.sidebar.attach.left=0,0
 main.sidebar.attach.right=100,0
-main.sidebar.widgets=sidebar.middle,sidebar.sash,sidebar.bottom
+main.sidebar.widgets=sidebar.middle
 
 sidebar.middle.type=container
 sidebar.middle.view=sidebar-list
 sidebar.middle.attach.top=0,0
-sidebar.middle.attach.bottom=
+sidebar.middle.attach.bottom=100,0
 sidebar.middle.attach.right=100,0
 sidebar.middle.attach.left=0,0
 #sidebar.middle.color=COLOR_LIST_BACKGROUND
 #sidebar.middle.fgcolor=COLOR_LIST_FOREGROUND
 
-sidebar.bottom.type=container
-sidebar.bottom.attach.top=sidebar.middle,0
-sidebar.bottom.attach.bottom=100,0
-sidebar.bottom.attach.right=100,0
-sidebar.bottom.attach.left=0,0
-sidebar.bottom.widgets=sidebar.friends
-
-sidebar.sash.type=h-mysash,sidebar.middle,sidebar.bottom
-sidebar.sash.view=sidebar-sash-bottom
-sidebar.sash.startpos=70%
-sidebar.sash.width=3
-sidebar.sash.background={image.sidebar.sashbg}
-sidebar.sash.background.drawmode=tile-x
-#sidebar.sash.border=thin,COLOR_WIDGET_NORMAL_SHADOW
-sidebar.sash.attach.top=sidebar.middle,0
-sidebar.sash.attach.left=0,0
-sidebar.sash.attach.right=100,0
-sidebar.sash.attach.bottom=
-
 main.sidebar.content.type=container
 main.sidebar.content.view=sidebar-contents
 main.sidebar.content.attach.top=0,0
diff --git a/com/aelitis/azureus/ui/skin/skin3_sidebar_friends.properties b/com/aelitis/azureus/ui/skin/skin3_sidebar_friends.properties
deleted file mode 100644
index dcc3a41..0000000
--- a/com/aelitis/azureus/ui/skin/skin3_sidebar_friends.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-
-sidebar.friends.type=container
-sidebar.friends.attach.template=template.fill
-sidebar.friends.widgets=friends.toolbar,\
-						buddies.viewer
-
-friends.toolbar.type=container
-friends.toolbar.view=toolbar-friends
-friends.toolbar.attach.top=0,0
-friends.toolbar.attach.left=0,0
-friends.toolbar.attach.right=100,0
diff --git a/com/aelitis/azureus/ui/skin/skin3_tab_browse.properties b/com/aelitis/azureus/ui/skin/skin3_tab_browse.properties
index b99e8bd..cc477c1 100644
--- a/com/aelitis/azureus/ui/skin/skin3_tab_browse.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_tab_browse.properties
@@ -21,10 +21,8 @@ browse.area.content.attach.bottom=100,0
 browse.area.content.forceVisibleAfterLoad=0
 
 browser.area.wait.type=text
-browser.area.wait.text={v3.MainWindow.Loading}
 browser.area.wait.text.color={color.text.fg}
 browser.area.wait.text.size=12
-browser.area.wait.attach.left=0,0
-browser.area.wait.attach.right=100,0
-browser.area.wait.attach.top=50,0
+browser.area.wait.attach.template=template.fill
+browser.area.wait.v-align=center
 browser.area.wait.align=center
diff --git a/com/aelitis/azureus/ui/skin/skin3_tab_searchresults.properties b/com/aelitis/azureus/ui/skin/skin3_tab_searchresults.properties
index 5ade92c..5f90855 100644
--- a/com/aelitis/azureus/ui/skin/skin3_tab_searchresults.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_tab_searchresults.properties
@@ -18,12 +18,10 @@ searchresults.area.content.attach.top=0,0
 searchresults.area.content.attach.bottom=searchresults.area.search-results
 
 searchresultsr.area.wait.type=text
-searchresultsr.area.wait.text={v3.MainWindow.Loading}
 searchresultsr.area.wait.text.color={color.text.fg}
 searchresultsr.area.wait.text.size=12
-searchresultsr.area.wait.attach.left=0,0
-searchresultsr.area.wait.attach.right=100,0
-searchresultsr.area.wait.attach.top=50,0
+searchresultsr.area.wait.attach.template=template.fill
+searchresultsr.area.wait.v-align=center
 searchresultsr.area.wait.align=center
 
 searchresults.area.search-results.type=browser
diff --git a/com/aelitis/azureus/ui/swt/Initializer.java b/com/aelitis/azureus/ui/swt/Initializer.java
index 54f4367..8a959c4 100644
--- a/com/aelitis/azureus/ui/swt/Initializer.java
+++ b/com/aelitis/azureus/ui/swt/Initializer.java
@@ -19,12 +19,16 @@
  */
 package com.aelitis.azureus.ui.swt;
 
+import java.io.File;
 import java.util.Iterator;
+import java.util.List;
 
 import org.eclipse.swt.widgets.Display;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.global.GlobalManager;
+import org.gudy.azureus2.core3.global.GlobalManagerDownloadRemovalVetoException;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.PluginEvent;
@@ -48,12 +52,12 @@ import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.messenger.ClientMessageContext;
 import com.aelitis.azureus.core.messenger.PlatformMessenger;
 import com.aelitis.azureus.core.messenger.config.PlatformConfigMessenger;
+import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.launcher.Launcher;
 import com.aelitis.azureus.ui.IUIIntializer;
 import com.aelitis.azureus.ui.InitializerListener;
 import com.aelitis.azureus.ui.UIFunctionsManager;
-import com.aelitis.azureus.ui.swt.browser.PlatformAuthorizedSenderImpl;
 import com.aelitis.azureus.ui.swt.browser.listener.*;
 import com.aelitis.azureus.ui.swt.browser.msg.MessageDispatcherSWT;
 import com.aelitis.azureus.ui.swt.content.RelatedContentUI;
@@ -126,14 +130,74 @@ public class Initializer
 		} else {
 
 			initializePlatformClientMessageContext();
-
-			PlatformMessenger.setAuthorizedTransferListener(new PlatformAuthorizedSenderImpl());
+			new AEThread2("cleanupOldStuff", true) {
+				public void run() {
+					cleanupOldStuff();
+				}
+			}.start();
 
 			PlatformConfigMessenger.login(ContentNetwork.CONTENT_NETWORK_VUZE, 0);
 			// typically the caller will call run() now 
 		}
 	}
 	
+	private void cleanupOldStuff() {
+		File v3Shares = new File(SystemProperties.getUserPath(), "v3shares");
+		if (v3Shares.isDirectory()) {
+			FileUtil.recursiveDeleteNoCheck(v3Shares);
+		}
+		File dirFriends = new File(SystemProperties.getUserPath(), "friends");
+		if (dirFriends.isDirectory()) {
+			FileUtil.recursiveDeleteNoCheck(dirFriends);
+		}
+		File dirMedia = new File(SystemProperties.getUserPath(), "media");
+		if (dirMedia.isDirectory()) {
+			FileUtil.recursiveDeleteNoCheck(dirMedia);
+		}
+		deleteConfig("v3.Friends.dat");
+		deleteConfig("unsentdata.config");
+		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+			public void azureusCoreRunning(final AzureusCore core) {
+				new AEThread2("cleanupOldStuff", true) {
+					public void run() {
+						GlobalManager gm = core.getGlobalManager();
+						List dms = gm.getDownloadManagers();
+						for (Object o : dms) {
+							DownloadManager dm = (DownloadManager) o;
+							if (dm != null) {
+								String val = PlatformTorrentUtils.getContentMapString(
+										dm.getTorrent(), "Ad ID");
+								if (val != null) {
+									try {
+										gm.removeDownloadManager(dm, true, true);
+									} catch (Exception e) {
+									}
+								}
+							}
+						}
+					}
+				}.start();
+			}
+		});
+	}
+
+	private void deleteConfig(String name) {
+		try {
+  		File file = new File(SystemProperties.getUserPath(), name);
+  		if (file.exists()) {
+  			file.delete();
+  		}
+		} catch (Exception e) {
+		}
+		try {
+  		File file = new File(SystemProperties.getUserPath(), name + ".bak");
+  		if (file.exists()) {
+  			file.delete();
+  		}
+		} catch (Exception e) {
+		}
+	}
+
 	public void runInSWTThread() {
 		COConfigurationManager.setBooleanDefault("ui.startfirst", true);
 		STARTUP_UIFIRST = STARTUP_UIFIRST
@@ -365,7 +429,7 @@ public class Initializer
 		}
 		
 		try{
-			new RelatedContentUI();
+			RelatedContentUI.getSingleton();
 			
 		}catch( Throwable e ){
 			
@@ -594,9 +658,6 @@ public class Initializer
 			clientMsgContext.addMessageListener(new VuzeListener());
 			clientMsgContext.addMessageListener(new DisplayListener(null));
 			clientMsgContext.addMessageListener(new ConfigListener(null));
-			clientMsgContext.addMessageListener(new LightBoxBrowserRequestListener());
-			clientMsgContext.addMessageListener(new StatusListener());
-			clientMsgContext.addMessageListener(new BrowserRpcBuddyListener());
 		}
 	}
 
diff --git a/com/aelitis/azureus/ui/swt/UIConfigDefaultsSWTv3.java b/com/aelitis/azureus/ui/swt/UIConfigDefaultsSWTv3.java
index d731a8f..01a423d 100644
--- a/com/aelitis/azureus/ui/swt/UIConfigDefaultsSWTv3.java
+++ b/com/aelitis/azureus/ui/swt/UIConfigDefaultsSWTv3.java
@@ -21,11 +21,12 @@
 package com.aelitis.azureus.ui.swt;
 
 import java.io.File;
+import java.util.Map;
 
-import org.gudy.azureus2.core3.config.impl.ConfigurationDefaults;
-import org.gudy.azureus2.core3.config.impl.ConfigurationManager;
-import org.gudy.azureus2.core3.config.impl.ConfigurationParameterNotFoundException;
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.impl.*;
 import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.core3.util.FileUtil;
 import org.gudy.azureus2.core3.util.SystemProperties;
 
 import com.aelitis.azureus.core.AzureusCore;
@@ -42,9 +43,11 @@ public class UIConfigDefaultsSWTv3
 	public static void initialize(AzureusCore core) {
 		ConfigurationManager config = ConfigurationManager.getInstance();
 
+		boolean configNeedsSave = false;
+
 		if (System.getProperty("FORCE_PROGRESSIVE", "").length() > 0) { //TODO HACK FOR DEMO PURPOSES ONLY!
 			config.setParameter("Prioritize First Piece", true);
-			config.save();
+			configNeedsSave = true;
 		}
 
 		// Up to az > 3.0.0.2, we did not store the original version the user starts
@@ -75,7 +78,7 @@ public class UIConfigDefaultsSWTv3
 				if (sDefSavePath != null && fNewPath.equals(new File(sDefSavePath))) {
 					sFirstVersion = "3.0.0.5";
 					config.setParameter("First Recorded Version", sFirstVersion);
-					config.save();
+					configNeedsSave = true;
 				}
 			}
 		}
@@ -105,7 +108,7 @@ public class UIConfigDefaultsSWTv3
 				if (sDefSavePath != null && fNewPath.equals(new File(sDefSavePath))) {
 					sFirstVersion = "3.0.0.5";
 					config.setParameter("First Recorded Version", sFirstVersion);
-					config.save();
+					configNeedsSave = true;
 				} else if (sDefSavePath == null
 						|| !fOldPath.equals(new File(sDefSavePath))) {
 					sFirstVersion = "2.5.0.0"; // guess
@@ -141,8 +144,6 @@ public class UIConfigDefaultsSWTv3
 			defaults.addParameter("auto_remove_inactive_items", false);
 			
 			defaults.addParameter("show_torrents_menu", false);
-			
-			config.save();
 		}
 
 
@@ -152,11 +153,11 @@ public class UIConfigDefaultsSWTv3
 		defaults.addParameter(SkinConstants.VIEWID_PLUGINBAR + ".visible", false);
 		config.removeParameter("v3.home-tab.starttab");
 		defaults.addParameter("v3.topbar.height", 60);
-		defaults.addParameter("v3.Start Advanced", false);
 		defaults.addParameter("MyTorrentsView.table.style", 0);
 		defaults.addParameter("v3.Show Welcome", true);
 		
-		boolean startAdvanced = config.getBooleanParameter("v3.Start Advanced");
+    int userMode = COConfigurationManager.getIntParameter("User Mode");
+		boolean startAdvanced = userMode > 1;
 		defaults.addParameter("Library.viewmode", startAdvanced ? 1 : 0);
 		defaults.addParameter("LibraryDL.viewmode", startAdvanced ? 1 : 0);
 		defaults.addParameter("LibraryUnopened.viewmode", startAdvanced ? 1 : 0);
@@ -182,5 +183,40 @@ public class UIConfigDefaultsSWTv3
 				defaults.addParameter("Plugin.UPnP.upnp.alertdeviceproblems", false);
 			}
 		});
+		
+		// "v3.StartTab" didn't exist before 4209_B49 and is written at startup.
+		// Use it as indicator to reset columns so beta users get correct columns
+		// ("Big View" only).  As a backup (in addition to), reset on first 4210
+		// run
+		if (!COConfigurationManager.hasParameter("v3.StartTab", true)
+				|| (ConfigurationChecker.isNewVersion() && Constants.compareVersions(
+						Constants.getBaseVersion(), "4.2.1.0") == 0)) {
+			// Reset 'big' columns, remove some tables that no longer exist
+			Map map = FileUtil.readResilientConfigFile("tables.config");
+			if (map != null && map.size() > 0) {
+  			Object[] keys = map.keySet().toArray();
+  			boolean removedSome = false;
+  			for (int i = 0; i < keys.length; i++) {
+  				if (keys[i] instanceof String) {
+  					String sKey = (String) keys[i];
+  					if (sKey.endsWith(".big") || sKey.startsWith("Table.library-")
+  							|| sKey.startsWith("Table.Media")
+  							|| sKey.startsWith("Table.activity.table")
+  							|| sKey.equals("Table.Activity.big")
+  							|| sKey.equals("Table.Activity_SB")) {
+  						map.remove(sKey);
+  						removedSome = true;
+  					}
+  				}
+  			}
+  			if (removedSome) {
+  				FileUtil.writeResilientConfigFile("tables.config", map);
+  			}
+			}
+		}
+		
+		if (configNeedsSave) {
+			config.save();
+		}
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/browser/BrowserContext.java b/com/aelitis/azureus/ui/swt/browser/BrowserContext.java
index 4be1582..c3dbf55 100644
--- a/com/aelitis/azureus/ui/swt/browser/BrowserContext.java
+++ b/com/aelitis/azureus/ui/swt/browser/BrowserContext.java
@@ -40,12 +40,14 @@ import org.gudy.azureus2.plugins.utils.StaticUtilities;
 import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
 import com.aelitis.azureus.core.messenger.ClientMessageContextImpl;
+import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
 import com.aelitis.azureus.core.messenger.browser.listeners.BrowserMessageListener;
 import com.aelitis.azureus.core.vuzefile.VuzeFile;
 import com.aelitis.azureus.core.vuzefile.VuzeFileHandler;
-import com.aelitis.azureus.plugins.net.netstatus.swt.NetStatusPluginTester.loggerProvider;
 import com.aelitis.azureus.ui.swt.browser.msg.MessageDispatcherSWT;
 import com.aelitis.azureus.util.ConstantsVuze;
 import com.aelitis.azureus.util.JSONUtils;
@@ -53,7 +55,7 @@ import com.aelitis.azureus.util.UrlFilter;
 
 /**
  * Manages the context for a single SWT {@link Browser} component,
- * including transactions, listeners and messages.
+ * including listeners and messages.
  * 
  * @author dharkness
  * @created Jul 19, 2006
@@ -84,7 +86,7 @@ public class BrowserContext
 	
 	private MessageDispatcherSWT messageDispatcherSWT;
 
-	protected boolean wiggleBrowser = org.gudy.azureus2.core3.util.Constants.isOSX;
+	protected boolean wiggleBrowser = Utils.isCarbon;
 
 	private torrentURLHandler		torrentURLHandler;
 
@@ -116,7 +118,25 @@ public class BrowserContext
 		browser 				= _browser;
 		forceVisibleAfterLoad 	= _forceVisibleAfterLoad;
 		widgetWaitIndicator 	= _widgetWaitingIndicator;
+/*		
+		BrowserFunction browserFunction = new BrowserFunction(browser, "sendMessageToClient") {
+			// @see org.eclipse.swt.browser.BrowserFunction#function(java.lang.Object[])
+			public Object function(Object[] arguments) {
+				if (arguments == null) {
+					debug("sendMessageToClient: arguments null on " + browser.getUrl());
+					return null;
+				}
+				if (arguments.length != 3) {
+					debug("sendMessageToClient: # arguments not 3 (" + arguments.length + ") on " + browser.getUrl());
+					return null;
+				}
 
+				BrowserMessage message = new BrowserMessage((String) arguments[0], (String) arguments[1], (Map<?, ?>) arguments[2]);
+				messageDispatcherSWT.dispatch(message);
+				return null;
+			}
+		};
+*/
 		// System.out.println( "Registered browser context: id=" + getID());
 		
 		messageDispatcherSWT = new MessageDispatcherSWT(this);
@@ -193,7 +213,7 @@ public class BrowserContext
 				/*
 				 * The browser might have been disposed already by the time this method is called 
 				 */
-				if(true == browser.isDisposed()){
+				if (browser.isDisposed() || browser.getShell().isDisposed()) {
 					return;
 				}
 				
@@ -217,7 +237,7 @@ public class BrowserContext
 				/*
 				 * The browser might have been disposed already by the time this method is called 
 				 */
-				if(true == browser.isDisposed()){
+				if (browser.isDisposed() || browser.getShell().isDisposed()) {
 					return;
 				}
 				
@@ -259,10 +279,13 @@ public class BrowserContext
 		
 		browser.addOpenWindowListener(new OpenWindowListener() {
 			public void open(WindowEvent event) {
+				if (browser.isDisposed() || browser.getShell().isDisposed()) {
+					return;
+				}
 				event.required = true;
 				
 				if (browser.getUrl().contains("js.debug=1")) {
-  				Shell shell = new Shell(Utils.findAnyShell(), SWT.SHELL_TRIM);
+  				Shell shell = ShellFactory.createMainShell(SWT.SHELL_TRIM);
   				shell.setLayout(new FillLayout());
 					Browser subBrowser = new Browser(shell,
 							Utils.getInitialBrowserStyle(SWT.NONE));
@@ -302,6 +325,9 @@ public class BrowserContext
 			private TimerEvent timerevent;
 
 			public void changed(LocationEvent event) {
+				if (browser.isDisposed() || browser.getShell().isDisposed()) {
+					return;
+				}
 				debug("browser.changed " + event.location);
 				if (timerevent != null) {
 					timerevent.cancel();
@@ -338,8 +364,7 @@ public class BrowserContext
 				/*
 				 * The browser might have been disposed already by the time this method is called 
 				 */
-				
-				if ( browser.isDisposed()){
+				if (browser.isDisposed() || browser.getShell().isDisposed()) {
 					return;
 				}
 				
@@ -368,8 +393,8 @@ public class BrowserContext
 
 				if (blocked) {
 					event.doit = false;
-					Utils.openMessageBox(Utils.findAnyShell(), SWT.OK, "URL blocked",
-							"Tried to open " + event_location + " but it's blocked");
+					new MessageBoxShell(SWT.OK, "URL blocked", "Tried to open "
+							+ event_location + " but it's blocked").open(null);
 					browser.back();
 				} else {
 					if (UrlFilter.getInstance().isWhitelisted(event_location)) {
@@ -647,10 +672,12 @@ public class BrowserContext
 		}
 
 		// System.out.println( "Unregistered browser context: id=" + getID());
-	
-		browser.setData(CONTEXT_KEY, null);
-		browser.removeDisposeListener(this);
-		messageDispatcherSWT.deregisterBrowser(browser);
+
+		if (!browser.isDisposed()) {
+  		browser.setData(CONTEXT_KEY, null);
+  		browser.removeDisposeListener(this);
+  		messageDispatcherSWT.deregisterBrowser(browser);
+		}
 		browser = null;
 
 		if (checkURLEvent != null && !checkURLEvent.isCancelled()) {
diff --git a/com/aelitis/azureus/ui/swt/browser/PlatformAuthorizedSenderImpl.java b/com/aelitis/azureus/ui/swt/browser/PlatformAuthorizedSenderImpl.java
deleted file mode 100644
index aa53c20..0000000
--- a/com/aelitis/azureus/ui/swt/browser/PlatformAuthorizedSenderImpl.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * Created on May 15, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.ui.swt.browser;
-
-import java.net.URL;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.browser.ProgressEvent;
-import org.eclipse.swt.browser.ProgressListener;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.widgets.Shell;
-
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.ui.swt.Utils;
-
-import com.aelitis.azureus.core.messenger.PlatformAuthorizedSender;
-import com.aelitis.azureus.core.messenger.PlatformMessenger;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.utils.SWTLoginUtils;
-
-/**
- * @author TuxPaper
- * @created May 15, 2008
- *
- */
-public class PlatformAuthorizedSenderImpl
-	implements PlatformAuthorizedSender
-{
-	String s = null;
-
-	private Shell shell = null;
-
-	/**
-	 * 
-	 */
-	public PlatformAuthorizedSenderImpl() {
-	}
-
-	// @see com.aelitis.azureus.core.messenger.PlatformAuthorizedSender#startDownload(java.net.URL, java.lang.String, org.gudy.azureus2.core3.util.AESemaphore, boolean)
-	public void startDownload(final URL url, final String data,
-			final AESemaphore sem_waitDL, final boolean loginAndRetry) {
-		Utils.execSWTThread(new AERunnable() {
-			boolean[] isRetry = { false };
-
-			public void runSupport() {
-				try {
-					boolean ourShell = false;
-					Shell shell = PlatformAuthorizedSenderImpl.this.shell;
-					if (shell == null) {
-						UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-						if (uiFunctions != null) {
-							shell = uiFunctions.getMainShell();
-						}
-						if (shell != null) {
-							PlatformAuthorizedSenderImpl.this.shell = shell;
-						} else {
-							shell = new Shell();
-							shell.setVisible(false);
-							ourShell= true;
-						}
-					}
-					final Browser browser = new Browser(shell,
-							Utils.getInitialBrowserStyle(SWT.NONE));
-					browser.setVisible(false);
-					if (ourShell) {
-						final Shell shellFinal = shell; 
-						browser.addDisposeListener(new DisposeListener() {
-							public void widgetDisposed(DisposeEvent e) {
-								// better safe than sorry, don't dispose shell while
-								// the browser which is in the shell is being disposed
-								Utils.execSWTThreadLater(0, new AERunnable() {
-									public void runSupport() {
-										shellFinal.dispose();
-									}
-								});
-							}
-						});
-					}
-
-					// Safari doesn't return getText() when results aren't text/html
-					// IE removes /n when in text/html mode
-					String responseType = Constants.isOSX ? "text/html" : "text/plain";
-					
-					final String fullUrl = url + "?" + data
-							+ "&responseType=" + responseType;
-					PlatformMessenger.debug("Open Auth URL: "
-							+ url + " in " + responseType + "\n" + fullUrl);
-
-					browser.addProgressListener(new ProgressListener() {
-						public void completed(ProgressEvent event) {
-							parseAuthorizedListenerResult(browser, sem_waitDL, isRetry,
-									loginAndRetry);
-						}
-
-						public void changed(ProgressEvent event) {
-						}
-					});
-					
-					browser.setUrl(fullUrl);
-
-				} catch (Throwable e) {
-
-					Debug.printStackTrace(e);
-
-					sem_waitDL.release();
-				}
-			}
-		});
-	}
-
-	private void parseAuthorizedListenerResult(final Browser browser,
-			final AESemaphore sem_waitDL, boolean[] isRetry, boolean loginAndRetry) {
-		if (browser.isDisposed()) {
-			sem_waitDL.release();
-			return;
-		}
-		
-		boolean	went_async = false;
-		
-		try {
-			s = browser.getText();
-
-			// authFail message is "authentication required"
-			// catch a little bit more, just in case 
-			boolean authFail = s.indexOf(";exception;") > 0
-					&& s.indexOf("authenticat") > 0 && s.indexOf("required") > 0;
-
-			int i = s.indexOf("0;");
-
-			if (i < 0) {
-				String partial = s.length() == 0 ? "" : s.substring(0, Math.min(200,
-						s.length()));
-				PlatformMessenger.debug("Got BAD Auth Reply ( " + s.length() + "): "
-						+ partial);
-			}
-
-			if ( authFail && loginAndRetry && !isRetry[0]){
-				
-				s = null;
-
-				isRetry[0] = true;
-
-				went_async = true;
-				
-				SWTLoginUtils.waitForLogin(new SWTLoginUtils.loginWaitListener() {
-					public void loginComplete() {
-						// once the page is reloaded ProgressListener.complete will be
-						// triggered again
-						
-						browser.refresh();
-					}
-					
-					public void loginCanceled() {
-						browser.dispose();
-						sem_waitDL.release();
-					}
-				});
-			} else {
-				if (i > 0) {
-					s = s.substring(i);
-				}
-				// On PPC, we get a JVM crash on disposal, so maybe this delay will
-				// fix it.
-				if (Constants.isOSX) {
-					Utils.execSWTThreadLater(0, new AERunnable() {
-						public void runSupport() {
-							browser.dispose();
-						}
-					});
-				} else {
-					browser.dispose();
-				}
-			}
-		} finally {
-			
-			if ( !went_async ){
-			
-				sem_waitDL.release();
-			}
-		}
-	}
-
-	public String getResults() {
-		return s;
-	}
-	
-	public void clearResults() {
-		s = null;
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/AbstractBrowserRequestListener.java b/com/aelitis/azureus/ui/swt/browser/listener/AbstractBrowserRequestListener.java
deleted file mode 100644
index 759a830..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/AbstractBrowserRequestListener.java
+++ /dev/null
@@ -1,175 +0,0 @@
-package com.aelitis.azureus.ui.swt.browser.listener;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.core.messenger.browser.listeners.AbstractBrowserMessageListener;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * This is a convenience abstract base class for listeners to browser requests;
- * it will automatically parse the <code>BrowserMessage</code> and call the appropriate methods.
- * <p>
- * This implementation also caches the parameter values and exposes them through accessor methods
- * for convenience so subclasses do not have to parser and store them locally.
- * <p>
- * Subclasses must provide the implementation for {@link IBrowserRequestListener#handleOpenURL()},
- * and may override other handlers as needed. 
- * @author knguyen
- *
- */
-public abstract class AbstractBrowserRequestListener
-	extends AbstractBrowserMessageListener
-	implements IBrowserRequestListener
-{
-
-	public static final String LISTENER_ID = "lightbox-browser";
-
-	protected Map decodedMap = new HashMap(0);
-
-	private String url = null;
-
-	private String redirectURL = null;
-
-	private String prefixVerifier = null;
-
-	private int width = -1;
-
-	private int height = -1;
-
-	private boolean isMovable = false;
-
-	private boolean isResizable = false;
-
-	public AbstractBrowserRequestListener() {
-		super(LISTENER_ID);
-	}
-
-	public void handleMessage(BrowserMessage message) {
-
-		String opID = message.getOperationId();
-		decodedMap = message.getDecodedMap();
-		if (true == OP_OPEN_URL.equals(opID)) {
-			handleOpenURL();
-		} else if (true == OP_CLOSE.equals(opID)) {
-			handleClose();
-		} else if (true == OP_REFRESH.equals(opID)) {
-			handleRefresh();
-		} else if (true == OP_RESIZE.equals(opID)) {
-			handleResize();
-		}
-
-	}
-
-	public int getHeight() {
-		if (true == decodedMap.containsKey(OP_OPEN_URL_PARAM_HEIGHT)) {
-			height = MapUtils.getMapInt(decodedMap, OP_OPEN_URL_PARAM_HEIGHT, -1);
-		}
-
-		return height;
-	}
-	
-	public String getCallback() {
-		return MapUtils.getMapString(decodedMap, OP_OPEN_URL_PARAM_CALLBACK, null);
-	}
-	
-	public String getPrefixVerifier() {
-		if (true == decodedMap.containsKey(OP_OPEN_URL_PARAM_TITLE_PREFIX_VERIFIER)) {
-			prefixVerifier = MapUtils.getMapString(decodedMap,
-					OP_OPEN_URL_PARAM_TITLE_PREFIX_VERIFIER, "");
-		}
-
-		return prefixVerifier;
-	}
-
-	public String getURL() {
-		if (true == decodedMap.containsKey(OP_OPEN_URL_PARAM_URL)) {
-			url = MapUtils.getMapString(decodedMap, OP_OPEN_URL_PARAM_URL, "");
-		}
-
-		return url;
-	}
-
-	public int getWidth() {
-		if (true == decodedMap.containsKey(OP_OPEN_URL_PARAM_WIDTH)) {
-			width = MapUtils.getMapInt(decodedMap, OP_OPEN_URL_PARAM_WIDTH, -1);
-		}
-
-		return width;
-	}
-
-	public boolean isMovable() {
-		if (true == decodedMap.containsKey(OP_OPEN_URL_PARAM_MOVABLE)) {
-			isMovable = MapUtils.getMapBoolean(decodedMap, OP_OPEN_URL_PARAM_MOVABLE,
-					false);
-		}
-		return isMovable;
-	}
-
-	public boolean isResizable() {
-		if (true == decodedMap.containsKey(OP_OPEN_URL_PARAM_RESIZABLE)) {
-			isResizable = MapUtils.getMapBoolean(decodedMap,
-					OP_OPEN_URL_PARAM_RESIZABLE, false);
-		}
-		return isResizable;
-	}
-
-	public String getStatusMessage() {
-		/*
-		 * Do not cache the status message since it need to be matched with the current close message
-		 */
-		if (true == decodedMap.containsKey(OP_CLOSE_PARAM_STATUS)) {
-			return MapUtils.getMapString(decodedMap, OP_CLOSE_PARAM_STATUS, null);
-		}
-		return null;
-	}
-
-	public String getDisplayMessage() {
-		/*
-		 * Do not cache the display message since it need to be matched with the current close message
-		 */
-		if (true == decodedMap.containsKey(OP_CLOSE_PARAM_DISPLAY)) {
-			return MapUtils.getMapString(decodedMap, OP_CLOSE_PARAM_DISPLAY, null);
-		}
-		return null;
-	}
-
-	public String getRedirectURL() {
-		if (true == decodedMap.containsKey(OP_OPEN_URL_PARAM_REDIRECT_URL)) {
-			redirectURL = MapUtils.getMapString(decodedMap,
-					OP_OPEN_URL_PARAM_REDIRECT_URL, "");
-		}
-
-		return redirectURL;
-	}
-
-	public boolean isRedirect() {
-		if (true == decodedMap.containsKey(OP_CLOSE_PARAM_ON_CLOSE)) {
-			String onCloseValue = MapUtils.getMapString(decodedMap,
-					OP_CLOSE_PARAM_ON_CLOSE, null);
-			if (null != onCloseValue && true == onCloseValue.equals("redirect")) {
-				return true;
-			}
-
-		}
-		return false;
-	}
-
-	public void handleClose() {
-		// Do nothing by default; subclass may override
-	}
-
-	public void handleRefresh() {
-		// Do nothing by default; subclass may override
-	}
-
-	public void handleResize() {
-		// Do nothing by default; subclass may override
-	}
-
-	public void handleOpenURL() {
-		// Do nothing by default; subclass may override
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/AbstractBuddyPageListener.java b/com/aelitis/azureus/ui/swt/browser/listener/AbstractBuddyPageListener.java
deleted file mode 100644
index 0d93355..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/AbstractBuddyPageListener.java
+++ /dev/null
@@ -1,248 +0,0 @@
-package com.aelitis.azureus.ui.swt.browser.listener;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.graphics.Point;
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.progress.ProgressReportMessage;
-import org.json.simple.JSONObject;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.core.messenger.browser.listeners.AbstractBrowserMessageListener;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * This is a convenience abstract base class for listeners to the add buddy page;
- * it will automatically parse the <code>BrowserMessage</code> and call the appropriate methods.
- *
- * @author knguyen
- *
- */
-public abstract class AbstractBuddyPageListener
-	extends AbstractBrowserMessageListener
-	implements IBuddyPageListener
-{
-
-	public static final String LISTENER_ID = "buddy-page";
-
-	protected Map decodedMap = new HashMap(0);
-
-	protected Browser browser;
-
-	private Map confirmationResponse = null;
-
-	private String invitationMessage = "";
-
-	private Point size = new Point(-1, -1);
-
-	private String windowState = null;
-
-	private int invitationsSent = 0;
-
-	private String message_success = MessageText.getString("message.status.success");
-
-	public AbstractBuddyPageListener(Browser browser) {
-		super(LISTENER_ID);
-		this.browser = browser;
-	}
-
-	public void handleMessage(final BrowserMessage message) {
-		if (true == Constants.isCVSVersion()) {
-			System.out.println(message.getFullMessage());//KN: sysout
-		}
-
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				String opID = message.getOperationId();
-				decodedMap = message.getDecodedMap();
-				if (true == OP_CLOSE.equals(opID)) {
-					handleClose();
-				} else if (true == OP_CANCEL.equals(opID)) {
-					handleCancel();
-				} else if (true == OP_INVITEES.equals(opID)) {
-
-					if (true == decodedMap.containsKey(OP_INVITEES_PARAM_BUDDIES)) {
-						handleBuddyInvites();
-					}
-					if (true == decodedMap.containsKey(OP_INVITEES_PARAM_EMAILS)) {
-						handleEmailInvites();
-					}
-
-				} else if (true == OP_INVITE_CONFIRM.equals(opID)) {
-					if (true == decodedMap.containsKey(OP_INVITE_CONFIRM_PARAM_MSG)) {
-						Object getmessageObj = decodedMap.get(OP_INVITE_CONFIRM_PARAM_MSG);
-						if (getmessageObj instanceof Map) {
-							confirmationResponse = (Map) getmessageObj;
-
-							List sentInvitations = MapUtils.getMapList(confirmationResponse,
-									"sentInvitations", Collections.EMPTY_LIST);
-							invitationsSent = sentInvitations.size();
-
-						} else {
-							confirmationResponse = null;
-						}
-						handleInviteConfirm();
-					}
-				}
-
-				else if (true == OP_RESIZE.equals(opID)) {
-
-					if (true == decodedMap.containsKey(OP_RESIZE_PARAM_WINDOW_STATE)) {
-						windowState = decodedMap.get(OP_RESIZE_PARAM_WINDOW_STATE).toString();
-						if (null != windowState) {
-							if (false == windowState.equals(OP_RESIZE_PARAM_STATE_MAXIMIZE)
-									&& false == windowState.equals(OP_RESIZE_PARAM_STATE_MINIMIZE)
-									&& false == windowState.equals(OP_RESIZE_PARAM_STATE_RESTORE)) {
-								windowState = null;
-							}
-						}
-					} else {
-						if (true == decodedMap.containsKey(OP_RESIZE_PARAM_WIDTH)) {
-							size.x = Integer.parseInt(decodedMap.get(OP_RESIZE_PARAM_WIDTH).toString());
-						}
-						if (true == decodedMap.containsKey(OP_RESIZE_PARAM_HEIGHT)) {
-							size.y = Integer.parseInt(decodedMap.get(OP_RESIZE_PARAM_HEIGHT).toString());
-						}
-					}
-					handleResize();
-				} else if( OP_INVITEES_UPDATE.equals(opID)) {
-					try {
-						int nbInvitees = Integer.parseInt(decodedMap.get(OP_INVITEES_PARAM_NB_INVITEES).toString());
-						handleNbBuddiesUpdated(nbInvitees);
-					}catch (Exception e) {
-						// TODO: handle exception
-					}
-				}
-			}
-		});
-
-	}
-
-	public List getInvitedBuddies() {
-
-		if (true == decodedMap.containsKey(OP_INVITEES_PARAM_BUDDIES)) {
-
-			List invitedBuddies = new ArrayList();
-
-			List invitedBuddyMaps = MapUtils.getMapList(decodedMap,
-					OP_INVITEES_PARAM_BUDDIES, new ArrayList());
-
-			for (Iterator iterator = invitedBuddyMaps.iterator(); iterator.hasNext();) {
-				JSONObject map = (JSONObject) iterator.next();
-				VuzeBuddy vBuddy = VuzeBuddyManager.createPotentialBuddy(null);
-				vBuddy.setDisplayName(map.get("displayName").toString());
-				vBuddy.setLoginID(map.get("name").toString());
-				invitedBuddies.add(vBuddy);
-			}
-
-			return invitedBuddies;
-		}
-
-		return Collections.EMPTY_LIST;
-	}
-
-	public List getInvitedEmails() {
-		if (true == decodedMap.containsKey(OP_INVITEES_PARAM_EMAILS)) {
-			return MapUtils.getMapList(decodedMap, OP_INVITEES_PARAM_EMAILS,
-					new ArrayList());
-		}
-		return Collections.EMPTY_LIST;
-	}
-
-	public Map getConfirmationResponse() {
-		return confirmationResponse;
-	}
-
-	public String getInvitationMessage() {
-		return invitationMessage;
-	}
-
-	public List getConfirmationMessages() {
-		Map response = getConfirmationResponse();
-		List message = new ArrayList();
-
-		if (null != response && false == response.isEmpty()) {
-
-			List sentInvitations = MapUtils.getMapList(response, "sentInvitations",
-					Collections.EMPTY_LIST);
-			if (null != sentInvitations && false == sentInvitations.isEmpty()) {
-				for (Iterator iterator = sentInvitations.iterator(); iterator.hasNext();) {
-					Object object = (Object) iterator.next();
-					if (object instanceof Map) {
-						Map invitation = (Map) object;
-						String msg = MapUtils.getMapString(invitation, "value", "");
-						msg += " : ";
-
-						if (true == MapUtils.getMapBoolean(invitation, "success", false)) {
-							msg += message_success;
-							message.add(new ProgressReportMessage(msg,
-									ProgressReportMessage.MSG_TYPE_INFO));
-						} else {
-							msg += MapUtils.getMapString(invitation, "cause", "");
-							message.add(new ProgressReportMessage(msg,
-									ProgressReportMessage.MSG_TYPE_ERROR));
-						}
-					}
-				}
-			}
-
-		}
-
-		return message;
-	}
-
-	public String getFormattedInviteMessage() {
-		String message;
-		int successMessages = 0;
-		int errorMessages = 0;
-
-		List messages = getConfirmationMessages();
-		for (Iterator iterator = messages.iterator(); iterator.hasNext();) {
-			ProgressReportMessage msg = (ProgressReportMessage) iterator.next();
-			if (true == msg.isInfo()) {
-				successMessages++;
-			} else {
-				errorMessages++;
-			}
-
-		}
-
-		if (errorMessages == 0) {
-			if (successMessages == 1) {
-				message = MessageText.getString("message.confirm.invite.singular");
-			} else if (successMessages > 1) {
-				message = MessageText.getString("message.confirm.invite.plural");
-			} else {
-				message = "DEBUG: confirmation with no error and no success???";
-			}
-		} else {
-			message = MessageText.getString("message.confirm.invite.error");
-		}
-
-		return message;
-	}
-
-	public Point getSize() {
-		return size;
-	}
-
-	public String getWindowState() {
-		return windowState;
-	}
-
-	public int getInvitationsSent() {
-		return invitationsSent;
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/AbstractStatusListener.java b/com/aelitis/azureus/ui/swt/browser/listener/AbstractStatusListener.java
deleted file mode 100644
index a2b341c..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/AbstractStatusListener.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package com.aelitis.azureus.ui.swt.browser.listener;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.core3.util.Debug;
-
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.core.messenger.browser.listeners.AbstractBrowserMessageListener;
-import com.aelitis.azureus.util.ConstantsVuze;
-import com.aelitis.azureus.util.MapUtils;
-
-public abstract class AbstractStatusListener
-	extends AbstractBrowserMessageListener
-	implements IStatusMessageListener
-{
-	protected Map decodedMap = new HashMap(0);
-
-	public AbstractStatusListener(String listenerID) {
-		super(listenerID);
-	}
-
-	public void handleMessage(BrowserMessage message) {
-		if (context != null
-				&& context.getContentNetworkID() != ConstantsVuze.DEFAULT_CONTENT_NETWORK_ID) {
-			context.debug("ERROR: Got Login JS RPC from non default network.  Ignoring");
-			Debug.out("ERROR: Got Login JS RPC from non default network.  Ignoring");
-			return;
-		}
-
-		String opID = message.getOperationId();
-		if (true == Constants.isCVSVersion()) {
-			System.out.println("\tLogin status message: " + message.getFullMessage());//KN: sysout
-		}
-		/*
-		 * When no parameter is supplied the BrowserMessage throws an exception;
-		 * it really should be returning a null.
-		 */
-		try {
-			decodedMap = message.getDecodedMap();
-		} catch (Exception e) {
-			decodedMap = new HashMap(0);
-		}
-		if (true == OP_LOGIN_UPDATE.equals(opID)) {
-			handleLoginUpdate();
-		} else if (true == OP_LOGIN_STATUS.equals(opID)) {
-			handleLoginStatus();
-		} else if (true == OP_PAGE_LOAD_COMPLETED.equals(opID)) {
-			handlePageLoadCompleted();
-		}
-
-	}
-
-	public String getUserName() {
-		if (true == decodedMap.containsKey(OP_LOGIN_UPDATE_PARAM_USER_NAME)) {
-			return MapUtils.getMapString(decodedMap, OP_LOGIN_UPDATE_PARAM_USER_NAME,
-					"");
-		}
-		return null;
-
-	}
-
-	public String getAvatar() {
-		if (true == decodedMap.containsKey(OP_LOGIN_UPDATE_PARAM_AVATAR)) {
-			return MapUtils.getMapString(decodedMap, OP_LOGIN_UPDATE_PARAM_AVATAR,
-					"");
-		}
-		return null;
-
-	}
-
-	public String getDisplayName() {
-		if (true == decodedMap.containsKey(OP_LOGIN_UPDATE_PARAM_DISPLAY_NAME)) {
-			return MapUtils.getMapString(decodedMap,
-					OP_LOGIN_UPDATE_PARAM_DISPLAY_NAME, "");
-		}
-
-		return null;
-	}
-
-	public String getPK() {
-		if (true == decodedMap.containsKey(OP_PK)) {
-			return MapUtils.getMapString(decodedMap, OP_PK, "");
-		}
-
-		return null;
-	}
-
-	/**
-	 * Called when a login state has changed
-	 * Default implementation does nothing; subclasses may override
-	 */
-	public void handleLoginUpdate() {
-	}
-
-	/**
-	 * Called to report the current login status
-	 * Default implementation does nothing; subclasses may override
-	 */
-	public void handleLoginStatus() {
-	}
-
-	/**
-	 * Called when a browser page has completed loading it's content
-	 * Default implementation does nothing; subclasses may override
-	 */
-	public void handlePageLoadCompleted() {
-	}
-
-	public boolean isRegistrationStillOpen() {
-		if (true == decodedMap.containsKey(OP_LOGIN_UPDATE_PARAM_REGISTRATION_OPEN)) {
-			return MapUtils.getMapBoolean(decodedMap,
-					OP_LOGIN_UPDATE_PARAM_REGISTRATION_OPEN, true);
-		}
-		return true;
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/BrowserRpcBuddyListener.java b/com/aelitis/azureus/ui/swt/browser/listener/BrowserRpcBuddyListener.java
deleted file mode 100644
index 15de783..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/BrowserRpcBuddyListener.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Created on Apr 21, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
- 
-package com.aelitis.azureus.ui.swt.browser.listener;
-
-import java.util.*;
-
-import org.gudy.azureus2.core3.util.SystemTime;
-
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.core.messenger.browser.listeners.AbstractBrowserMessageListener;
-import com.aelitis.azureus.core.messenger.config.PlatformBuddyMessenger;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.util.ConstantsV3;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author TuxPaper
- * @created Apr 21, 2008
- *
- */
-public class BrowserRpcBuddyListener
-extends AbstractBrowserMessageListener
-{
-	private static final String DEFAULT_LISTENER_ID = "buddy";
-
-	public static final String OP_ACCEPT = "accept";
-
-	public static final String OP_INVITE = "invite";
-
-	public static final String OP_SYNC = "sync";
-
-	public BrowserRpcBuddyListener() {
-		super(DEFAULT_LISTENER_ID);
-	}
-
-	// @see com.aelitis.azureus.ui.swt.browser.msg.AbstractMessageListener#handleMessage(com.aelitis.azureus.ui.swt.browser.msg.BrowserMessage)
-	public void handleMessage(BrowserMessage message) {
-		try {
-			String opid = message.getOperationId();
-
-			Map decodedMap = message.getDecodedMap();
-
-			if (OP_ACCEPT.equals(opid)) {
-				Map mapBuddy = MapUtils.getMapMap(decodedMap, "buddy", Collections.EMPTY_MAP);
-				String code = MapUtils.getMapString(decodedMap, "code", null);
-				VuzeBuddyManager.log("buddy accept " + mapBuddy.get("login-id") + "/" + code);
-				
-				if (mapBuddy.size() > 0) {
-					List pkList = MapUtils.getMapList(mapBuddy, "pks",
-							Collections.EMPTY_LIST);
-					String[] pks = (String[]) pkList.toArray(new String[0]);
-
-					VuzeBuddyManager.acceptInvite(code, pks);
-				}
-			} else if (OP_INVITE.equals(opid)) {
-				VuzeBuddyManager.inviteWithShare(decodedMap, null, null, null);
-			} else if (OP_SYNC.equals(opid)) {
-				long last = MapUtils.getMapLong(decodedMap, "min-time-secs", 0);
-				if (SystemTime.getCurrentTime()
-						- PlatformBuddyMessenger.getLastSyncCheck() > last * 1000) {
-					PlatformBuddyMessenger.sync(null);
-				}
-			}
-		} catch (Throwable t) {
-			message.debug("handle Config message", t);
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/DisplayListener.java b/com/aelitis/azureus/ui/swt/browser/listener/DisplayListener.java
index 16926e6..1e9f116 100644
--- a/com/aelitis/azureus/ui/swt/browser/listener/DisplayListener.java
+++ b/com/aelitis/azureus/ui/swt/browser/listener/DisplayListener.java
@@ -8,7 +8,15 @@ import org.eclipse.swt.dnd.TextTransfer;
 import org.eclipse.swt.dnd.Transfer;
 import org.eclipse.swt.widgets.Display;
 
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.PluginManager;
+import org.gudy.azureus2.plugins.ui.UIInstance;
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.UIManagerListener;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.donations.DonationWindow;
@@ -21,24 +29,19 @@ import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
 import com.aelitis.azureus.core.messenger.browser.listeners.AbstractBrowserMessageListener;
 import com.aelitis.azureus.core.subs.Subscription;
 import com.aelitis.azureus.core.subs.SubscriptionManagerFactory;
+import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
 import com.aelitis.azureus.ui.selectedcontent.*;
 import com.aelitis.azureus.ui.swt.shells.BrowserWindow;
 import com.aelitis.azureus.ui.swt.skin.*;
-import com.aelitis.azureus.ui.swt.views.skin.FriendsToolbar;
 import com.aelitis.azureus.ui.swt.views.skin.SkinViewManager;
 import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
 import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
 import com.aelitis.azureus.util.ContentNetworkUtils;
+import com.aelitis.azureus.util.JSONUtils;
 import com.aelitis.azureus.util.MapUtils;
 
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.PluginManager;
-import org.gudy.azureus2.plugins.ui.UIInstance;
-import org.gudy.azureus2.plugins.ui.UIManager;
-import org.gudy.azureus2.plugins.ui.UIManagerListener;
-
 public class DisplayListener
 	extends AbstractBrowserMessageListener
 {
@@ -63,13 +66,11 @@ public class DisplayListener
 
 	public static final String VZ_NON_ACTIVE = "vz-non-active";
 
-	public static final String OP_INVITE_FRIEND = "invite";
-
 	public static final String OP_SET_SELECTED_CONTENT = "set-selected-content";
 
-	public static final String OP_SHOW_DONATION_WINDOW = "show-donation-window";
+	public static final String OP_GET_SELECTED_CONTENT = "get-selected-content";
 
-	public static final String OP_INVITE_FRIEND_PARAM_MESSAGE = "message";
+	public static final String OP_SHOW_DONATION_WINDOW = "show-donation-window";
 
 	public static final String OP_OPEN_SEARCH = "open-search";
 
@@ -100,7 +101,7 @@ public class DisplayListener
 				launchUrl(MapUtils.getMapString(decodedMap, "url", null));
 			} else {
 				String ref = message.getReferer();
-				if (target.equals("browse") && ref != null) {
+				if (target != null && target.equals("browse") && ref != null) {
 					ContentNetwork cn = ContentNetworkManagerFactory.getSingleton().getContentNetworkForURL(
 							ref);
 					if (cn != null) {
@@ -171,21 +172,16 @@ public class DisplayListener
 		} else if (OP_REFRESH_TAB.equals(opid)) {
 			Map decodedMap = message.getDecodedMap();
 			refreshTab(MapUtils.getMapString(decodedMap, "browser-id", ""));
-		} else if (OP_INVITE_FRIEND.equals(opid)) {
-			Map decodedMap = message.getDecodedMap();
-			FriendsToolbar friendsToolbar = (FriendsToolbar) SkinViewManager.getByClass(FriendsToolbar.class);
-			if(friendsToolbar != null) {
-				friendsToolbar.addBuddy(MapUtils.getMapString(decodedMap, OP_INVITE_FRIEND_PARAM_MESSAGE,	null));
-			}
-			
-//			VuzeFriendUtils.getInstance().invite(
-//					MapUtils.getMapString(decodedMap, OP_INVITE_FRIEND_PARAM_MESSAGE,
-//							null));
 		} else if (OP_SET_SELECTED_CONTENT.equals(opid)) {
 			Map decodedMap = message.getDecodedMap();
 			if (decodedMap != null) {
 				setSelectedContent(message, decodedMap);
 			}
+		} else if (OP_GET_SELECTED_CONTENT.equals(opid)) {
+			Map decodedMap = message.getDecodedMap();
+			if (decodedMap != null) {
+				getSelectedContent(message, decodedMap);
+			}
 		} else if (OP_SHOW_DONATION_WINDOW.equals(opid)) {
 			Map decodedMap = message.getDecodedMap();
 			DonationWindow.open(true, MapUtils.getMapString(decodedMap, "source-ref",
@@ -201,6 +197,51 @@ public class DisplayListener
 		}
 	}
 
+	private void getSelectedContent(BrowserMessage message, Map decodedMap) {
+		String callback = MapUtils.getMapString(decodedMap, "callback", null);
+		if (callback == null) {
+			return;
+		}
+		
+		List<Map> list = new ArrayList<Map>();
+		
+		DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
+		for (DownloadManager dm : dms) {
+			if (dm != null) {
+				Map<String, Object> mapDM = new HashMap<String, Object>();
+				TOTorrent torrent = dm.getTorrent();
+				if (torrent != null && !TorrentUtils.isReallyPrivate(torrent)) {
+					try {
+  					// make a copy of the torrent
+  
+  					Map torrent_map = torrent.serialiseToMap();
+  					TOTorrent torrent_to_send = TOTorrentFactory.deserialiseFromMap( torrent_map );
+  					Map	vuze_map = (Map)torrent_map.get( "vuze" );
+  					// remove any non-standard stuff (e.g. resume data)
+  					torrent_to_send.removeAdditionalProperties();
+  					torrent_map = torrent_to_send.serialiseToMap();
+  					if ( vuze_map != null ){
+  						torrent_map.put( "vuze", vuze_map );
+  					}
+  					
+  					byte[] encode = BEncoder.encode(torrent_map);
+  					
+  					mapDM.put("name", PlatformTorrentUtils.getContentTitle2(dm));
+  					mapDM.put("torrent", Base32.encode(encode));
+  					
+  					list.add(mapDM);
+					} catch (Throwable t) {
+						Debug.out(t);
+					}
+				}
+			}
+		}
+		
+		if (list.size() > 0 && context != null) {
+			context.executeInBrowser(callback + "(" + JSONUtils.encodeToJSON(list) + ")");
+		}
+	}
+
 	/**
 	 * @param message 
 	 * @param decodedMap
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/IBrowserRequestListener.java b/com/aelitis/azureus/ui/swt/browser/listener/IBrowserRequestListener.java
deleted file mode 100644
index 3c8ff56..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/IBrowserRequestListener.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.aelitis.azureus.ui.swt.browser.listener;
-
-/**
- * An interface for listeners to a browser operation request
- * @author knguyen
- *
- */
-public interface IBrowserRequestListener
-{
-
-	public static final String OP_CLOSE = "close";
-	
-	public static final String OP_CLOSE_PARAM_STATUS = "status";
-	
-	public static final String OP_CLOSE_PARAM_DISPLAY = "display";
-	
-	public static final String OP_CLOSE_PARAM_ON_CLOSE = "on-close";
-
-	public static final String OP_REFRESH = "refresh";
-
-	public static final String OP_OPEN_URL = "open-url";
-
-	public static final String OP_OPEN_URL_PARAM_URL = "url";
-
-	public static final String OP_OPEN_URL_PARAM_CALLBACK = "callback";
-
-	public static final String OP_OPEN_URL_PARAM_WIDTH = "width";
-
-	public static final String OP_OPEN_URL_PARAM_HEIGHT = "height";
-
-	public static final String OP_OPEN_URL_PARAM_MOVABLE = "movable";
-	
-	public static final String OP_OPEN_URL_PARAM_RESIZABLE = "resizable";
-
-	public static final String OP_OPEN_URL_PARAM_TITLE_PREFIX_VERIFIER = "title-prefix-verifier";
-	
-	public static final String OP_OPEN_URL_PARAM_REDIRECT_URL = "redirect-url";
-
-	public static final String OP_RESIZE = "resize";
-
-	public static final String OP_RESIZE_PARAM_WIDTH = "width";
-
-	public static final String OP_RESIZE_PARAM_HEIGHT = "height";
-
-	public static final String OP_INVOKE_CALLBACK = "invoke-callback";
-
-	public void handleOpenURL();
-
-	public void handleResize();
-
-	public void handleClose();
-
-	public void handleRefresh();
-	
-	public boolean isMovable();
-	
-	public boolean isResizable();
-	
-	public int getWidth();
-	
-	public int getHeight();
-	
-	public String getPrefixVerifier();
-	
-	public String getURL();
-
-}
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/IBuddyPageListener.java b/com/aelitis/azureus/ui/swt/browser/listener/IBuddyPageListener.java
deleted file mode 100644
index e327fbd..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/IBuddyPageListener.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.aelitis.azureus.ui.swt.browser.listener;
-
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.swt.graphics.Point;
-
-public interface IBuddyPageListener
-{
-	public static final String OP_CLOSE = "close";
-
-	public static final String OP_CANCEL = "cancel";
-
-	public static final String OP_INVITEES = "buddy-invitees";
-
-	public static final String OP_INVITEES_PARAM_BUDDIES = "buddies";
-
-	public static final String OP_INVITEES_PARAM_EMAILS = "emails";
-
-	public static final String OP_INVITE_CONFIRM = "invite-confirm";
-
-	public static final String OP_INVITE_CONFIRM_PARAM_MSG = "message";
-
-	public static final String OP_RESIZE = "resize";
-
-	public static final String OP_RESIZE_PARAM_WIDTH = "width";
-
-	public static final String OP_RESIZE_PARAM_HEIGHT = "height";
-
-	public static final String OP_RESIZE_PARAM_WINDOW_STATE = "window_state";
-
-	public static final String OP_RESIZE_PARAM_STATE_MAXIMIZE = "maximize";
-
-	public static final String OP_RESIZE_PARAM_STATE_MINIMIZE = "minimize";
-
-	public static final String OP_RESIZE_PARAM_STATE_RESTORE = "restore";
-	
-	public static final String OP_INVITEES_UPDATE = "invitees-update";
-	
-	public static final String OP_INVITEES_PARAM_NB_INVITEES = "nb_invitees";
-
-	public void handleNbBuddiesUpdated(int nbInvites);
-	
-	public void handleClose();
-
-	public void handleCancel();
-
-	public void handleBuddyInvites();
-
-	public void handleEmailInvites();
-
-	public void handleInviteConfirm();
-
-	public void handleResize();
-
-	/**
-	 * Returns a list of <code>VuzeBuddy</code>; the list may be empty but never <code>null</code>
-	 * @return
-	 */
-	public List getInvitedBuddies();
-
-	public List getInvitedEmails();
-
-	public Map getConfirmationResponse();
-
-	public List getConfirmationMessages();
-
-	public Point getSize();
-
-	public String getWindowState();
-
-	public int getInvitationsSent();
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/IStatusMessageListener.java b/com/aelitis/azureus/ui/swt/browser/listener/IStatusMessageListener.java
deleted file mode 100644
index 9bc035d..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/IStatusMessageListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.aelitis.azureus.ui.swt.browser.listener;
-
-public interface IStatusMessageListener
-{
-
-	public static final String OP_PAGE_LOAD_COMPLETED = "page_load_completed";
-	
-	public static final String OP_LOGIN_STATUS = "login-status";
-	
-	public static final String OP_LOGIN_UPDATE = "login-update";
-
-	public static final String OP_LOGIN_UPDATE_PARAM_USER_NAME = "user-name";
-
-	public static final String OP_LOGIN_UPDATE_PARAM_AVATAR = "avatar.url";
-
-	public static final String OP_LOGIN_UPDATE_PARAM_DISPLAY_NAME = "display-name";
-	
-	public static final String OP_LOGIN_UPDATE_PARAM_REGISTRATION_OPEN = "registration-open";
-	
-	public static final String OP_PK = "pk";
-	
-	public void handleLoginStatus();
-	
-	public void handleLoginUpdate();
-	
-	public void handlePageLoadCompleted();
-
-	public String getUserName();
-
-	public String getDisplayName();
-	
-	public String getPK();
-
-	public boolean isRegistrationStillOpen();
-}
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/LightBoxBrowserListener.java b/com/aelitis/azureus/ui/swt/browser/listener/LightBoxBrowserListener.java
deleted file mode 100644
index 5b4682f..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/LightBoxBrowserListener.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package com.aelitis.azureus.ui.swt.browser.listener;
-
-import org.gudy.azureus2.core3.util.Debug;
-
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.ui.skin.SkinConstants;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.shells.LightBoxBrowserWindow;
-import com.aelitis.azureus.ui.swt.shells.main.UIFunctionsImpl;
-import com.aelitis.azureus.ui.swt.skin.SWTSkin;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectTab;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinTabSet;
-import com.aelitis.azureus.ui.swt.views.skin.SkinViewManager;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
-
-/**
- * A listener to requests from a LightBox browser window
- * 
- * @author knguyen
- *
- */
-public class LightBoxBrowserListener
-	extends AbstractBrowserRequestListener
-{
-
-	private LightBoxBrowserWindow browserWindow;
-
-	public LightBoxBrowserListener(LightBoxBrowserWindow browserWindow) {
-		super();
-		this.browserWindow = browserWindow;
-	}
-
-	public void handleResize() {
-		if (null != browserWindow) {
-			browserWindow.setSize(getWidth(), getHeight());
-		}
-	}
-
-	public void handleClose() {
-
-		if (null != browserWindow) {
-			browserWindow.close();
-		}
-
-		/*
-		 * If there is a status message attached then process it
-		 */
-		if (null != getStatusMessage()) {
-			try {
-				BrowserMessage statusMessage = new BrowserMessage(getStatusMessage());
-				new StatusListener().handleMessage(statusMessage);
-			} catch (Exception e) {
-				Debug.out(e);
-			}
-		}
-
-		if (true == isRedirect() && null != browserWindow.getRedirectURL()) {
-			UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-			if (null == uiFunctions) {
-				throw new IllegalStateException(
-						"No instance of UIFunctionsSWT found; the UIFunctionsManager might not have been initialized properly");
-			}
-
-			/*
-			 * Find the active browser (if any) and set it's URL to the RedirectURL
-			 */
-			if (uiFunctions instanceof UIFunctionsImpl) {
-				SideBar sidebar = (SideBar)SkinViewManager.getByClass(SideBar.class);
-				
-				// 3.2 TODO: Get active content area, check if has a browser, and set url
-				//           If that's still what we really want to do here..
-			}
-		}
-
-		if (null != getDisplayMessage()) {
-			try {
-				BrowserMessage displayMessage = new BrowserMessage(getDisplayMessage());
-
-				/*
-				 * Only the OPEN_URL operation really has any effect here since the rest of the operations
-				 * for 'display' require a reference to a standard browser which would be incompatible
-				 * with the new pop-up browser
-				 */
-				if (true == DisplayListener.OP_OPEN_URL.equals(displayMessage.getOperationId())) {
-					new DisplayListener(null).handleMessage(displayMessage);
-				}
-			} catch (Exception e) {
-				Debug.out(e);
-			}
-
-		}
-
-	}
-
-	public void handleRefresh() {
-		if (null != browserWindow) {
-			browserWindow.refresh();
-		}
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/LightBoxBrowserRequestListener.java b/com/aelitis/azureus/ui/swt/browser/listener/LightBoxBrowserRequestListener.java
deleted file mode 100644
index caaa8b6..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/LightBoxBrowserRequestListener.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.aelitis.azureus.ui.swt.browser.listener;
-
-import com.aelitis.azureus.ui.swt.shells.LightBoxBrowserWindow;
-
-/**
- * A listener to browser requests that responds with a LightBox browser window
- * <p>
- * This class is a good reference implementation that can be readily copied
- * for when we want to extend support for other types of browsers.
- * 
- * @author knguyen
- *
- */
-public class LightBoxBrowserRequestListener
-	extends AbstractBrowserRequestListener
-{
-
-	public LightBoxBrowserRequestListener() {
-		super();
-	}
-
-	public void handleOpenURL() {
-		LightBoxBrowserWindow lbWindow = new LightBoxBrowserWindow(getURL(),
-				getPrefixVerifier(), getWidth(), getHeight());
-
-		if (null != getRedirectURL()) {
-			lbWindow.setRedirectURL(getRedirectURL());
-		}
-		
-		lbWindow.setCallback(getCallback(), getContext());
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/MetaSearchListener.java b/com/aelitis/azureus/ui/swt/browser/listener/MetaSearchListener.java
index 4822bb4..876c6c1 100644
--- a/com/aelitis/azureus/ui/swt/browser/listener/MetaSearchListener.java
+++ b/com/aelitis/azureus/ui/swt/browser/listener/MetaSearchListener.java
@@ -1941,6 +1941,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 		
 		context.put( Engine.SC_FORCE_FULL, "true" );
 		
+		context.put( Engine.SC_BATCH_PERIOD, "1000" );
+		
 		if ( target == null ){
 		
 			metaSearchManager.getMetaSearch().search( listener, parameters, headers, context, max_per_engine );
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/StatusListener.java b/com/aelitis/azureus/ui/swt/browser/listener/StatusListener.java
deleted file mode 100644
index de1cc06..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/StatusListener.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.aelitis.azureus.ui.swt.browser.listener;
-
-import com.aelitis.azureus.util.LoginInfoManager;
-
-public class StatusListener
-	extends AbstractStatusListener
-{
-	public static final String LISTENER_ID = "status";
-
-	public StatusListener() {
-		super(LISTENER_ID);
-	}
-
-	public void handleLoginUpdate() {
-		LoginInfoManager.getInstance().setUserInfo(getUserName(), getDisplayName(),
-				getPK(), getAvatar());
-	}
-
-	public void handleLoginStatus() {
-		LoginInfoManager.getInstance().setUserInfo(getUserName(), getDisplayName(),
-				getPK(), getAvatar());
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/TorrentListener.java b/com/aelitis/azureus/ui/swt/browser/listener/TorrentListener.java
index ec9418d..1b87ba1 100644
--- a/com/aelitis/azureus/ui/swt/browser/listener/TorrentListener.java
+++ b/com/aelitis/azureus/ui/swt/browser/listener/TorrentListener.java
@@ -7,7 +7,6 @@ import org.eclipse.swt.widgets.Shell;
 
 import org.bouncycastle.util.encoders.Base64;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.*;
 
@@ -19,13 +18,10 @@ import com.aelitis.azureus.core.messenger.ClientMessageContext;
 import com.aelitis.azureus.core.messenger.ClientMessageContext.torrentURLHandler;
 import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
 import com.aelitis.azureus.core.messenger.browser.listeners.AbstractBrowserMessageListener;
-import com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfo;
 import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfoContentNetwork;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentV3;
 import com.aelitis.azureus.ui.swt.utils.TorrentUIUtilsV3;
-import com.aelitis.azureus.ui.swt.views.skin.VuzeShareUtils;
 import com.aelitis.azureus.util.MapUtils;
 
 public class TorrentListener
@@ -37,10 +33,6 @@ public class TorrentListener
 
 	public static final String OP_LOAD_TORRENT = "load-torrent";
 
-	public static final String OP_UPDATE_RATING = "update-rating";
-
-	public static final String OP_SHARE = "share-torrent";
-
 	private ClientMessageContext.torrentURLHandler		torrentURLHandler;
 	
 	public TorrentListener(String id) {
@@ -101,53 +93,11 @@ public class TorrentListener
 					}
 				});
 			}
-		} else if (OP_UPDATE_RATING.equals(opid)) {
-			Map decodedMap = message.getDecodedMap();
-			final String hash = MapUtils.getMapString(decodedMap, "torrent-hash", null);
-			if (hash == null) {
-				return;
-			}
-			AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
-				public void azureusCoreRunning(AzureusCore core) {
-					updateRating(core, hash);
-				}
-			});
-		} else if (OP_SHARE.equals(opid)) {
-			Map decodedMap = message.getDecodedMap();
-			String hash = MapUtils.getMapString(decodedMap, "torrent-hash", null);
-			String displayName = MapUtils.getMapString(decodedMap, "display-name",
-					null);
-			if (hash != null && displayName != null) {
-				String referer = MapUtils.getMapString(decodedMap, "referer",
-						"torrentlistener");
-				boolean canPlay = MapUtils.getMapBoolean(decodedMap, "can-play", false);
-				SelectedContentV3 content = new SelectedContentV3(hash,
-						displayName, true, canPlay);
-				content.setThumbURL(MapUtils.getMapString(decodedMap, "thumbnail.url",
-						null));
-				VuzeShareUtils.getInstance().shareContent(content, null, referer);
-			}
 		} else {
 			throw new IllegalArgumentException("Unknown operation: " + opid);
 		}
 	}
 
-	protected void updateRating(AzureusCore core, String hash) {
-		DownloadManager dm = core.getGlobalManager().getDownloadManager(
-				new HashWrapper(Base32.decode(hash)));
-		if (dm != null && dm.getTorrent() != null) {
-			PlatformRatingMessenger.getUserRating(
-					PlatformTorrentUtils.getContentNetworkID(dm.getTorrent()),
-					new String[] {
-				PlatformRatingMessenger.RATE_TYPE_CONTENT
-			}, new String[] {
-				hash
-			}, 7000);
-
-			PlatformRatingMessenger.updateGlobalRating(dm.getTorrent(), 7000);
-		}
-	}
-
 	public static boolean loadTorrentByB64(AzureusCore core, String b64) {
 		return loadTorrentByB64(core, null, b64);
 	}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/publish/LocalHoster.java b/com/aelitis/azureus/ui/swt/browser/listener/publish/LocalHoster.java
deleted file mode 100644
index 1d9be17..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/publish/LocalHoster.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.aelitis.azureus.ui.swt.browser.listener.publish;
-
-import java.io.File;
-import java.net.URL;
-
-public interface LocalHoster
-{
-	public URL hostFile(File f);
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/publish/PublishListener.java b/com/aelitis/azureus/ui/swt/browser/listener/publish/PublishListener.java
deleted file mode 100644
index 3fd93bf..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/publish/PublishListener.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Created on Jun 29, 2006 10:16:26 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.ui.swt.browser.listener.publish;
-
-import org.eclipse.swt.widgets.Shell;
-
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.core.messenger.browser.BrowserTransaction;
-import com.aelitis.azureus.core.messenger.browser.listeners.AbstractTransactionalListener;
-
-/**
- * Handles messages from the PublishNewContent page.
- * 
- * <ul>
- *   <li> choose-file </li>
- *   <li> choose-folder </li>
- *   <li> torrent-ready </li>
- * </ul>
- * 
- * @author dharkness
- * @created Jul 18, 2006
- */
-public class PublishListener extends AbstractTransactionalListener
-{
-    public static final String DEFAULT_LISTENER_ID = "publish";
-
-    public static final String OP_CHOOSE_FILE = "choose-file";
-    public static final String OP_CHOOSE_FOLDER = "choose-folder";
-    public static final String OP_CHOOSE_THUMBNAIL = "choose-thumbnail";
-    public static final String OP_EDIT_THUMBNAIL = "edit-thumbnail";
-    public static final String OP_TORRENT_READY = "torrent-ready";
-    public static final String OP_CANCEL = "cancel";
-    
-    
-    private Shell shell;
-    
-    private LocalHoster hoster;
-
-	public PublishListener(Shell s, LocalHoster hoster) {
-		this(s, DEFAULT_LISTENER_ID, hoster);
-	}
-
-	public PublishListener(Shell s, String id, LocalHoster hoster) {
-        super(id);
-        
-        this.shell = s;
-        this.hoster = hoster;
-        
-        registerOperationTxnRequiresNew(OP_CHOOSE_FILE);
-        registerOperationTxnRequiresNew(OP_CHOOSE_FOLDER);
-        registerOperationTxnMandatory(OP_CHOOSE_THUMBNAIL);
-        registerOperationTxnMandatory(OP_TORRENT_READY);        
-        registerOperationTxnRequired(OP_CANCEL);
-        registerOperationTxnRequiresNew(OP_EDIT_THUMBNAIL);
-    }
-
-    /**
-     * Handles the given message, usually by parsing the parameters 
-     * and calling the appropriate operation.
-     * 
-     * @param message holds all message information
-     */
-    public void handleTxnlMessage ( BrowserMessage message , BrowserTransaction txn ) {
-        PublishTransaction realTxn = (PublishTransaction) txn;
-        
-        realTxn.setShell(shell);
-        realTxn.setLocalHoster(hoster);
-        
-        if ( OP_CHOOSE_FILE.equals(message.getOperationId()) ) {
-            realTxn.chooseFile(message);
-        }
-        else if ( OP_CHOOSE_FOLDER.equals(message.getOperationId()) ) {
-            realTxn.chooseFolder(message);
-        }
-        else if ( OP_CHOOSE_THUMBNAIL.equals(message.getOperationId()) || OP_EDIT_THUMBNAIL.equals(message.getOperationId())) {
-            realTxn.chooseThumbnail(message);
-        }
-        else if ( OP_TORRENT_READY.equals(message.getOperationId()) ) {
-            realTxn.torrentIsReady(message);
-        }
-        else if ( OP_CANCEL.equals(message.getOperationId()) ) {
-            realTxn.cancel();
-        }
-        else {
-            throw new IllegalArgumentException("Unknown operation: " + message.getOperationId());
-        }
-    }
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/publish/PublishTransaction.java b/com/aelitis/azureus/ui/swt/browser/listener/publish/PublishTransaction.java
deleted file mode 100644
index 43e0660..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/publish/PublishTransaction.java
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * Created on Jun 29, 2006 10:16:26 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.ui.swt.browser.listener.publish;
-
-import java.io.*;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.internal.image.FileFormat;
-import org.eclipse.swt.widgets.*;
-
-import org.bouncycastle.util.encoders.Base64;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.DisplayFormatters;
-import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
-import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT.TriggerInThread;
-
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
-import com.aelitis.azureus.core.messenger.ClientMessageContext;
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.core.messenger.browser.BrowserTransaction;
-import com.aelitis.azureus.ui.swt.utils.ImageResizeException;
-import com.aelitis.azureus.ui.swt.utils.ImageResizer;
-import com.aelitis.azureus.util.MapUtils;
-import com.aelitis.azureus.util.PublishUtils;
-
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.torrent.*;
-
-
-/**
- * Tracks the progress of creating a torrent during the publish process.
- * 
- * @author dharkness
- * @created Jul 20, 2006
- */
-public class PublishTransaction extends BrowserTransaction
-{
-	
-	
-	private static final String ELEMENTS = "elements";
-
-	private static final int   DEFAULT_IMAGE_BOX_SIZE = 320;
-	private static final float DEFAULT_JPEG_QUALITY = 0.85f;
-	
-	private Shell shell;
-	
-	private LocalHoster hoster;
-	
-	private TorrentCreator creator;
-	private TorrentCreatorListener creatorListener;
-	private File dataFile;
-	
-	public void setShell(Shell shell) {
-		this.shell = shell;
-	}
-	
-	public void setLocalHoster(LocalHoster hoster) {
-		this.hoster = hoster;
-	}
-
-	/**
-     * Creates the transaction. Called by the manager.
-     * 
-     * @param id unique ID assigned by the manager
-     * @param type passed by manager
-     * @param context used to access the browser
-     */
-    public PublishTransaction ( int id , String type , ClientMessageContext context ) {
-        super(id, type, context);
-    }
-
-
-    /**
-     * Opens a file dialog so the user can choose the file to torrent.
-     */
-    public void chooseFile ( BrowserMessage message ) {    	
-    	Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-        	FileDialog dialog = new FileDialog(shell);    	
-        	String file = dialog.open();    	
-        	createTorrentFile(file);
-				}
-    	});
-    }
-
-    /**
-     * Opens a file dialog so the user can choose the folder to torrent.
-     */
-    public void chooseFolder ( BrowserMessage message ) {
-    	Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-		    	DirectoryDialog dialog = new DirectoryDialog(shell);    	
-		    	String file = dialog.open();
-		    	createTorrentFile(file);
-				}
-			});
-    }
-    
-    protected boolean canceling ( ) {
-    	if(creator != null) {
-    		creator.cancel();
-    		creator.removeListener(creatorListener);
-    		creator = null;
-    		//Gudy	sendBrowserMessage("torrent","canceled");
-    	}
-        return true;
-    }
-    
-    /**
-     * Opens a file dialog so the user can choose the image to use as a thumbnail
-     */
-    public void chooseThumbnail(final BrowserMessage message) {
-    	// Not absolutely sure if core needs to be running, but
-    	// ensure for safety
-    	CoreWaiterSWT.waitForCore(TriggerInThread.SWT_THREAD, new AzureusCoreRunningListener() {
-				public void azureusCoreRunning(AzureusCore core) {
-					_chooseThumbnail(message);
-				}
-			});
-    }
-
-    private void _chooseThumbnail(BrowserMessage message) {
-    	final int resize_size[] = {DEFAULT_IMAGE_BOX_SIZE,DEFAULT_IMAGE_BOX_SIZE};
-    	final float image_quality[] = {DEFAULT_JPEG_QUALITY};
-    	Map elements = null; //will be used if several thumbnails are required on a single page
-        if ( message.isParamObject() ) {
-            Map parameters = message.getDecodedMap();
-    		try {
-    			resize_size[0] = MapUtils.getMapInt(parameters, "width", 
-    					DEFAULT_IMAGE_BOX_SIZE);
-    			resize_size[1] = MapUtils.getMapInt(parameters, "height", 
-    					DEFAULT_IMAGE_BOX_SIZE);
-    			image_quality[0] = ((Number) MapUtils.getMapObject(parameters,
-						"quality", new Double(DEFAULT_JPEG_QUALITY), Number.class)).floatValue();
-    			if (parameters.containsKey(ELEMENTS)){
-    				elements = (Map) parameters.get(ELEMENTS);
-    			}
-    		} catch(Exception e) {
-    			//Possible bad parameters given, use default values
-    			e.printStackTrace();
-    		}
-        }
-    	FileDialog dialog = new FileDialog(shell,SWT.OPEN);
-    	dialog.setFilterNames(new String[] {"Image Files"});
-    	dialog.setFilterExtensions(new String[] {"*.jpg;*.jpeg;*.bmp;*.gif;*.png;*.tiff,*.tif"});
-    	final String fileName = dialog.open();
-    	if(fileName != null) {
-    		//Run async not to block the UI
-			/*Thread runner = 
-                new Thread("Thumbnail Creator") {
-    				public void run() {*/
-    		
-    					try {
-                            sendBrowserMessage("thumb", "start", elements);
-                            
-        					File file = new File(fileName);
-				ResizedImageInfo info = loadAndResizeImage(file, resize_size[0],
-						resize_size[1], 1);
-    	    				if(info == null) {
-    	    					debug("User canceled image resizing");
-    	    					sendBrowserMessage("thumb", "clear", elements);
-    	    				} else {
-	    	    				final String thumbURL = info.url.toString();
-	    	    				debug("Size : " + info.data.length);
-	    	    				
-	    	    				final String encoded = new String(Base64.encode(info.data));
-	                            Map params = new HashMap();
-	                            params.put("url", thumbURL);
-	                            params.put("width", new Long(info.width));
-	                            params.put("height", new Long(info.height));
-	                            params.put("data", encoded);
-	                            if ( elements != null ){
-	                            	params.put(ELEMENTS, elements);
-	                            }
-	                            sendBrowserMessage("thumb", "done", params);
-    	    				}
-        	    		}
-    					catch(ImageResizeException e) {
-    						debug("Error resizing image",e);
-    						sendBrowserMessage("thumb", "clear", elements);
-                            
-                            Map params = new HashMap();
-                            params.put("message", e.getMessage());
-                            sendBrowserMessage("page", "error",params);
-    					}
-			catch (Exception e) {
-				debug("Error reading file", e);
-				sendBrowserMessage("thumb", "clear", elements);
-
-				Map params = new HashMap();
-				String errmsg = e.getMessage();
-				
-				params.put("message",
-						"Vuze cannot process this image. " + 
-						"Please select another one.\n\nDetailed Error: " + errmsg);
-				sendBrowserMessage("page", "error", params);
-			}
-                        catch (OutOfMemoryError e) {
-                        	debug("Error processing the image",e);
-                        	
-                        	sendBrowserMessage("thumb", "clear", elements);
-                            
-                            Map params = new HashMap();
-                            params.put("message", "Vuze cannot process this image (likely reason is that it is too big). Please select another one.");
-                            sendBrowserMessage("page", "error",params);
-                        	
-                        }
-    				/*}
-			    };
-			runner.setDaemon(true);
-			runner.start();    	*/		
-    	}
-    }
-
- 	/**
-	 * Pulls the modified torrent from the result web page and saves it locally.
-	 */
-	public void torrentIsReady(BrowserMessage message) {
-		String torrent = MapUtils.getMapString(message.getDecodedMap(),
-				"torrent", null);
-		if (torrent != null) {
-			torrentIsReady(torrent);
-		}
-	}
-
-    protected void torrentIsReady(String strTorrent) {
-
-		try {
-			strTorrent = strTorrent.replaceAll("\\n", "");
-			debug("data file path = [" + dataFile.getPath() + "]");
-			debug("Torrent is ready, size = " + strTorrent.length()
-					+ ", content (base64) : " + strTorrent);
-
-			byte[] torrent_data = Base64.decode(strTorrent);
-
-			debug("Torrent Byte Length: " + torrent_data.length /* + ", content : " + new String(torrent_data) */);
-
-			// use PluginInterface since it has nice functions for
-			// setting complete and adding a download via Torrent
-			PluginInterface pi = PluginInitializer.getDefaultInterface();
-			Torrent torrent = pi.getTorrentManager().createFromBEncodedData(
-					torrent_data);
-
-			torrent.setDefaultEncoding();
-			torrent.setComplete(dataFile);
-
-			final Download download = pi.getDownloadManager().addDownload(torrent,
-					null, dataFile);
-
-			PublishUtils.setPublished(download);
-
-			download.setForceStart(true);
-
-			//Transaction is finished
-			stop();
-		} catch (Throwable t) {
-			Debug.out("torrentIsReady", t);
-		}
-	} 
-
-
-    private void torrentCreationFailed(Exception cause) {
-    	debug("Torrent Creation Failed", cause);
-    	
-    	sendBrowserMessage("torrent","failed");
-    	
-    	Map params = new HashMap();
-		params.put("message", "Vuze cannot process this file. Please select another file.");
-		sendBrowserMessage("page", "error",params);
-		
-    }
-    
-    private void createTorrentFile(String file) {
-    	if(file != null) {   		
-    		dataFile = new File(file);
-    		try {
-    			PluginInterface pi = PluginInitializer.getDefaultInterface();
-    			creator = pi.getTorrentManager().createFromDataFileEx(dataFile,
-						new URL("http://xxxxxxxxxxxxxxxxx:6969/announce"), false);
-
-    			creatorListener = new TorrentCreatorListener() {
-
-    				public void complete(Torrent torrent) {    					
-    					try {
-    						
-    						torrent.setDefaultEncoding();
-    						
-    						debug("local torrent creation complete: " +torrent.getName()+ " : " +torrent.getMagnetURI() );        						    						
-    						
-    						final String tData = new String( Base64.encode( torrent.writeToBEncodedData() ) );
-    						Map params = new HashMap();
-                            params.put("data", tData);
-    						sendBrowserMessage("torrent", "done", params);
-    					}
-    					catch (Throwable t) {
-    						// TODO: handle exception
-    						debug("error encoding torrent", t);
-    					}
-
-    				}
-
-    				public void failed(TorrentException cause) {
-    					torrentCreationFailed(cause);
-    				}
-
-    				public void reportActivity(String activity) {
-    					//debug("creation status : " + activity);
-    				}
-
-    				public void reportPercentageDone(int percent) {
-    					//debug("creation progress : " + percent);
-    					Map params = new HashMap();
-    					params.put("percent", new Long(percent));
-    					sendBrowserMessage("torrent", "progress", params);
-    				}
-
-    			};
-
-    			creator.addListener(creatorListener);
-
-    			creator.start();
-
-    		} catch (MalformedURLException e) {
-    			
-    			torrentCreationFailed(e);
-				
-    		} catch (TorrentException e) {
-    			
-    			torrentCreationFailed(e);
-				
-    		}
-            
-            Map params = new HashMap();
-            params.put("folder", new Boolean(dataFile.isDirectory()));
-            params.put("name", dataFile.getName());
-            Long[] info = getSizeAndCount(dataFile);
-            params.put("size", info[0]);
-            params.put("num-files", info[1]);
-            params.put("size-text", DisplayFormatters.formatByteCountToKiBEtc(info[0].longValue()));
-            sendBrowserMessage("torrent", "chosen", params);
-    	} else {
-    		//No file was chosen, cancel the transaction
-    		cancel();
-            stop();
-    	}
-    }
-    
-    private Long[] getSizeAndCount(File folderFile) {
-    	if (folderFile.isFile()) {
-    		return new Long[] { new Long(folderFile.length()), new Long(1) };
-    	}
-    	if (folderFile.isDirectory()) {
-    		long size = 0;
-    		long numFiles = 0;
-    		File[] files = folderFile.listFiles();
-    		if (files != null) {
-    			for (int i = 0; i < files.length; i++) {
-						File file = files[i];
-						Long[] sizeAndCount = getSizeAndCount(file);
-						size += sizeAndCount[0].longValue();
-						numFiles += sizeAndCount[1].longValue();
-					}
-    		}
-    		return new Long[] { new Long(size), new Long(numFiles) };
-    	}
-    	return new Long[] { new Long(0), new Long(0) };
-    }
-
-    private class ResizedImageInfo {
-    	public URL url;
-    	public int width,height;
-    	public byte[] data;
-    	
-    	public ResizedImageInfo(URL url,int width, int height, byte[] data) {
-    		this.url = url;
-    		this.width = width;
-    		this.height = height;
-    		this.data = data;
-    	}
-    }
-    
-    
-	private ResizedImageInfo loadAndResizeImage(final File f,
-			final int width, final int height, float quality)
-			throws Exception {
-		ImageLoader loader = new ImageLoader();
-		final Display display = shell.getDisplay();
-		Image source = null;
-		try {
-			source = new Image(shell.getDisplay(), f.getAbsolutePath());
-		} catch (Error e) {
-		}
-		
-		if (source == null) {
-			throw new ImageResizeException("Unable to read image.  Please choose another.");
-		}
-
-		// If size is already an exact match, and the file isn't too big, use
-		// original file
-		Rectangle bounds = source.getBounds();
-		try {
-			if (bounds.width == width && bounds.height == height
-					&& f.length() < 60000 && false) {
-				URL url = hoster.hostFile(f);
-				final FileInputStream fos = new FileInputStream(f);
-				byte[] buf = new byte[(int) f.length()];
-				fos.read(buf);
-				fos.close();
-
-				ResizedImageInfo result = new ResizedImageInfo(url, width, height, buf);
-				return result;
-			}
-		} catch (Exception e) {
-			Debug.out(e);
-		}
-
-		ImageResizer resizer = new ImageResizer(display, width, height, shell);
-
-		Image output = resizer.resize(source);
-		if (output == null)
-			return null;
-		ImageData data = output.getImageData();
-		//Dispose the image
-		if (output != null && !output.isDisposed()) {
-			output.dispose();
-		}
-
-		//debug("final ByteArrayOutputStream baos = new ByteArrayOutputStream();");
-		final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
-		loader.data = new ImageData[] { data
-		};
-		
-		String ext;
-		if (SWT.getVersion() >= 3500) {
-			// XXX Bug in SWT which borks some PNGs.. thus we can't use PNG saving
-			//     at all until they fix it.. See 
-			//     https://bugs.eclipse.org/bugs/show_bug.cgi?id=172290
-			loader.save(baos, SWT.IMAGE_PNG);
-			ext = ".png";
-		} else {
-			try {
-				Class cJPGFF = Class.forName("org.eclipse.swt.internal.image.JPEGFileFormat");
-
-				Constructor jpgConst = cJPGFF.getDeclaredConstructor(new Class[0]);
-
-				jpgConst.setAccessible(true);
-
-				FileFormat format = (FileFormat) jpgConst.newInstance(new Object[0]);
-
-				Field field = cJPGFF.getDeclaredField("encoderQFactor");
-
-				field.setAccessible(true);
-
-				field.setInt(format, (int) (quality * 100));
-
-				Class claLEDataOS = Class.forName("org.eclipse.swt.internal.image.LEDataOutputStream");
-
-				Constructor le_constructor = claLEDataOS.getDeclaredConstructor(new Class[] { OutputStream.class
-				});
-
-				le_constructor.setAccessible(true);
-
-				Object le_stream = le_constructor.newInstance(new Object[] { baos
-				});
-
-				Method unloadIntoStream = cJPGFF.getMethod("unloadIntoStream",
-						new Class[] {
-							ImageLoader.class,
-							claLEDataOS
-						});
-
-				try {
-					unloadIntoStream.invoke(format, new Object[] {
-						loader,
-						le_stream
-					});
-				} catch (Exception ex) {
-					//Too bad for us here
-					//However we don't want to try the other way, as it may be an io 
-					//exception, ie the stream is corrupted...
-					ex.printStackTrace();
-				}
-			} catch (Exception e) {
-				e.printStackTrace();
-				// The reflection way failed, do it the normal way with default 
-				// (0.75) quality...
-				loader.save(baos, SWT.IMAGE_JPEG);
-			}
-			ext = ".jpg";
-		}
-
-
-		byte[] bs = baos.toByteArray();
-
-		File fDest = File.createTempFile("thumbnail", ext);
-		FileOutputStream fos = new FileOutputStream(fDest);
-		fos.write(bs);
-		fos.close();
-
-		URL url = hoster.hostFile(fDest);
-		ResizedImageInfo result = new ResizedImageInfo(url, width, height, bs);
-
-		return result;
-	}
-
-    /*
-    private ResizedImageInfo loadAndResizeImage(File f,int thumbnail_size,float quality) throws Exception {
-    	
-    	debug("BufferedImage src = ImageIO.read(f);");
-    	BufferedImage src = ImageIO.read(f);                      
-        
-        BufferedImage image;
-        
-        int width = src.getWidth(),height = src.getHeight();
-        
-        float wRatio = (float)width / (float)thumbnail_size;
-        float hRatio = (float)height / (float)thumbnail_size;
-        
-        
-        
-        boolean mustResize = false;
-        
-        if(wRatio >= hRatio && wRatio > 1) {
-        	mustResize = true;
-        	width = thumbnail_size;
-        	height = (int) (src.getHeight() / wRatio);
-        }
-        if(hRatio > wRatio && hRatio > 1) {
-        	mustResize = true;
-        	width = (int) (src.getWidth() / hRatio);
-        	height = thumbnail_size;
-        	
-        }
-        
-        if(mustResize) {
-        	debug("mustResize");
-        	
-        	debug("Image img = src.getScaledInstance(width,height,Image.SCALE_FAST);");
-        	Image img = src.getScaledInstance(width,height,Image.SCALE_FAST);
-        	
-        	img.
-        	
-        	debug("BufferedImage copy = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);");
-        	BufferedImage copy = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
-        	
-        	debug("Graphics2D g2 = copy.createGraphics();");
-        	Graphics2D g2 = copy.createGraphics();
-        	
-        	debug("g2.setColor(Color.white);");
-        	g2.setColor(Color.white);
-        	
-        	debug("g2.fillRect(0,0,width,height);");
-        	g2.fillRect(0,0,width,height);
-        	
-        	debug("g2.drawImage(img, 0, 0, null);");
-        	g2.drawImage(img, 0, 0, new ImageObserver() {
-        		public boolean imageUpdate(Image arg0, int arg1, int arg2, int arg3, int arg4, int arg5) {
-        			debug("image update");
-        			return true;
-        		}
-        	});
-        	
-        	debug("g2.dispose();");
-        	g2.dispose();
-        	
-        	src = copy;
-        }
-        
-        
-        debug("File fDest = File.createTempFile(\"thumbnail\",\".jpg\");");
-        File fDest = File.createTempFile("thumbnail",".jpg");
-        
-        debug("final FileOutputStream fos = new FileOutputStream(fDest);");
-		final FileOutputStream fos = new FileOutputStream(fDest);
-		
-		debug("final ByteArrayOutputStream baos = new ByteArrayOutputStream();");
-		final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-		
-		
-		debug("OutputStream os = new OutputStream() {...};");
-		OutputStream os = new OutputStream() {
-			public void write(int arg0) throws java.io.IOException {fos.write(arg0);baos.write(arg0);};
-			public void flush() throws java.io.IOException {fos.flush();baos.flush();};
-			public void write(byte[] arg0) throws java.io.IOException {fos.write(arg0);baos.write(arg0);};
-			public void write(byte[] arg0, int arg1, int arg2) throws java.io.IOException {fos.write(arg0);baos.write(arg0);};			
-		};
-		
-		ImageOutputStream output = null;
-		
-		try {
-			//Get Writer and set compression
-			debug("Iterator iter = ImageIO.getImageWritersByFormatName(\"JPG\");");
-			Iterator iter = ImageIO.getImageWritersByFormatName("JPG");
-			
-			if (iter.hasNext()) {
-				
-				debug("ImageWriter writer = (ImageWriter)iter.next();");
-				ImageWriter writer = (ImageWriter)iter.next();
-				
-				debug("ImageWriteParam iwp = writer.getDefaultWriteParam();");
-				ImageWriteParam iwp = writer.getDefaultWriteParam();
-				
-				debug("ImageWriteParam iwp = writer.getDefaultWriteParam();");
-				
-				debug("iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);");
-				iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);		        
-		        
-				debug("iwp.setCompressionQuality(quality);");
-		        iwp.setCompressionQuality(quality);
-		        
-		        debug("ImageOutputStream output = new MemoryCacheImageOutputStream(os);");
-		        output = new MemoryCacheImageOutputStream(os);
-		        
-		        debug("writer.setOutput(output);");
-		        writer.setOutput(output);
-		        
-		        debug("IIOImage imageOut =  new IIOImage(src, null, null);");
-		        IIOImage imageOut =  new IIOImage(src, null, null);
-		        
-		        debug("writer.write(null, imageOut, iwp);");
-		        writer.write(null, imageOut, iwp);
-		    }
-        }catch (Exception e) {
-        	e.printStackTrace();
-		} finally {
-			output.close();			
-		}
-		
-		URL url = hoster.hostFile(fDest);
-		ResizedImageInfo result = new ResizedImageInfo(url,width,height,baos.toByteArray());
-		return result;
-        
-        
-    }
-    */
-}
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/publish/SeedingListener.java b/com/aelitis/azureus/ui/swt/browser/listener/publish/SeedingListener.java
deleted file mode 100644
index ae41e10..0000000
--- a/com/aelitis/azureus/ui/swt/browser/listener/publish/SeedingListener.java
+++ /dev/null
@@ -1,332 +0,0 @@
-package com.aelitis.azureus.ui.swt.browser.listener.publish;
-
-import java.util.*;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.global.GlobalManager;
-import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
-import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
-
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.core.messenger.browser.listeners.AbstractBrowserMessageListener;
-import com.aelitis.azureus.util.MapUtils;
-import com.aelitis.azureus.util.PublishUtils;
-
-public class SeedingListener
-	extends AbstractBrowserMessageListener
-{
-
-	private static final long INFINITE_ETA = 31535999; //1 year
-
-	private static final long STOPPED_ETA = -88;
-
-	private static final long ERROR_ETA = -99;
-
-	private static final String JS_UPLOAD_PROGRESS_MSG_KEY = "upload-progress";
-
-	private static final String JS_INDIVI_UPDATE_MSG_OP = "torrents";
-
-	private static final String JS_GLOBAL_UPDATE_MSG_OP = "global";
-
-	public static final String DEFAULT_LISTENER_ID = "seeding";
-
-	public static final String OP_SEND_UPDATE = "send-update";
-
-	public static final String OP_REMOVE = "remove";
-
-	public static final String OP_STOP = "stop";
-
-	public static final String OP_START = "start";
-
-	public SeedingListener() {
-		this(DEFAULT_LISTENER_ID);
-	}
-
-	public SeedingListener(String id) {
-		super(id);
-	}
-
-	public void handleMessage(BrowserMessage message) {
-		if (OP_SEND_UPDATE.equals(message.getOperationId())) {
-			sendUpdate();
-		} else if (OP_REMOVE.equals(message.getOperationId())) {
-			String id = MapUtils.getMapString(message.getDecodedMap(), "id", null);
-			if (id != null) {
-				removeTorrent(id);
-			}
-		} else if (OP_START.equals(message.getOperationId())) {
-			String id = MapUtils.getMapString(message.getDecodedMap(), "id", null);
-			if (id != null) {
-				startTorrent(id);
-			}
-		} else if (OP_STOP.equals(message.getOperationId())) {
-			String id = MapUtils.getMapString(message.getDecodedMap(), "id", null);
-			if (id != null) {
-				stopTorrent(id);
-			}
-		} else {
-			throw new IllegalArgumentException("Unknown operation: "
-					+ message.getOperationId());
-		}
-	}
-
-	private DownloadManager getDM(AzureusCore core, String magnet) {
-		return core.getGlobalManager().getDownloadManager(
-				new HashWrapper(Base32.decode(magnet)));
-	}
-
-	private void removeTorrent(final String id) {
-		CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
-			public void azureusCoreRunning(AzureusCore core) {
-
-				final DownloadManager dm = getDM(core, id);
-				
-				if (PublishUtils.isPublished(dm)) {
-					PublishUtils.setPublished(dm, false);
-					ManagerUtils.remove(dm, null, false, false, new AERunnable() {
-						public void runSupport() {
-							PublishUtils.setPublished(dm);
-						}
-					});
-				}
-			}
-		});
-	}
-
-	private void startTorrent(final String id) {
-		CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
-			public void azureusCoreRunning(AzureusCore core) {
-
-				final DownloadManager dm = getDM(core, id);
-
-    		if (dm != null) {
-    			try {
-    				dm.setForceStart(true);
-    			} catch (Exception e) {
-    				e.printStackTrace();
-    			}
-    		}
-			}
-		});
-	}
-
-	private void stopTorrent(final String id) {
-		CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
-			public void azureusCoreRunning(AzureusCore core) {
-
-				final DownloadManager dm = getDM(core, id);
-				stop(dm);
-			}
-		});
-	}
-
-	private void stop(DownloadManager dm) {
-		try {
-			ManagerUtils.stop(dm, null);
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	private void sendUpdate() {
-		try {
-			GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
-			if (gm == null) {
-				return;
-			}
-			List dmsArray = gm.getDownloadManagers();
-			if (dmsArray == null) {
-				return;
-			}
-
-			Object[] dms = dmsArray.toArray();
-
-			boolean hasIncompletePublish = false;
-			long totSeedingBytes = 0;
-			long totSeedingBytesRemaining = 0;
-			long total_up_rate_bps = 0;
-
-			int num_actually_uploading = 0;
-
-			ArrayList indiv_torrents = new ArrayList();
-
-			for (int i = dms.length - 1; i >= 0; i--) { //loop through all the running torrents
-
-				DownloadManager d = (DownloadManager) dms[i];
-
-				if (PublishUtils.isPublished(d)) { //this one we're uploading as published
-
-					//TODO use something more explicit than swarm availability / uploaded bytes
-
-					long download_size = d.getTorrent().getSize();
-
-					int percent_done = -1;
-					if (d.getState() == DownloadManager.STATE_SEEDING
-							&& d.getDownloadState().isOurContent()
-							&& d.getStats().getAvailability() < 2) {
-						TRTrackerScraperResponse scrape = d.getTrackerScrapeResponse();
-						int numSeeds = scrape.getSeeds();
-						long seedingStartedOn = d.getStats().getTimeStartedSeeding();
-						if ((numSeeds > 0) && (seedingStartedOn > 0)
-								&& (scrape.getScrapeStartTime() > seedingStartedOn))
-							numSeeds--;
-
-						if (numSeeds == 0) {
-							float availability = d.getStats().getAvailability();
-							float pctDone = ((int)availability) - availability;
-							percent_done = (int) (pctDone * 100);
-						} else {
-							percent_done = 100;
-						}
-					}
-					
-					if (percent_done < 0) {
-						percent_done = (int) ((d.getStats().getTotalDataBytesSent() * 100) / download_size);
-					}
-
-					if (percent_done > 99) { //100% uploaded
-						indiv_torrents.add(new IndividualProgress(d.getTorrent().getHash(),
-								d.getDisplayName(), 100, 0));
-					} else { //upload still in progress
-						hasIncompletePublish = true;
-
-						long eta = INFINITE_ETA; //so it shows infinity						
-
-						if (d.getState() == DownloadManager.STATE_STOPPED) {
-							eta = STOPPED_ETA;
-						} else if (d.getState() == DownloadManager.STATE_ERROR) {
-							eta = ERROR_ETA;
-						} else {
-							num_actually_uploading++; //running and upload still needed
-
-							totSeedingBytes += download_size;
-
-							long remaining = (long) (download_size * ((float) (100 - percent_done) / 100)); //rough
-
-							totSeedingBytesRemaining += remaining; //global stats
-
-							long up_rate_bps = d.getStats().getDataSendRate();
-
-							if (up_rate_bps > 0) {
-								total_up_rate_bps += up_rate_bps; //global stats
-
-								eta = remaining / up_rate_bps; //seconds remaining
-							}
-						}
-
-						indiv_torrents.add(new IndividualProgress(d.getTorrent().getHash(),
-								d.getDisplayName(), percent_done, eta));
-					}
-				}
-			}
-
-			if (!indiv_torrents.isEmpty()) { //there is something to update				
-
-				long g_percent = 100;
-				long g_eta = INFINITE_ETA;
-
-				if (totSeedingBytes > 0) { //there is still torrent data to upload
-					g_percent = ((totSeedingBytes - totSeedingBytesRemaining) * 100)
-							/ totSeedingBytes;
-
-					if (total_up_rate_bps > 0) {
-						g_eta = totSeedingBytesRemaining / total_up_rate_bps; //seconds remaining					
-					}
-
-					if (num_actually_uploading < 1) { //all in stopped state
-						g_eta = STOPPED_ETA;
-						g_percent = 0;
-					}
-				} else if (!hasIncompletePublish) { //done uploading
-					g_eta = 0;
-				}
-
-				List torrents = new ArrayList();
-
-				for (Iterator it = indiv_torrents.iterator(); it.hasNext();) {
-					IndividualProgress ind = (IndividualProgress) it.next();
-
-					long mod_eta = ind.eta;
-
-					if (g_eta > 0 && ind.eta > g_eta) { //for user display purposes, limit indiv eta to max what the global eta is showing
-						mod_eta = g_eta;
-					}
-
-					torrents.add(constructJSTorrentProgress(ind.infohash, ind.name,
-							ind.percent, mod_eta));
-				}
-
-				context.sendBrowserMessage(JS_UPLOAD_PROGRESS_MSG_KEY,
-						JS_GLOBAL_UPDATE_MSG_OP, constructJSGlobalProgress((int) g_percent,
-								g_eta));
-
-				context.sendBrowserMessage(JS_UPLOAD_PROGRESS_MSG_KEY,
-						JS_INDIVI_UPDATE_MSG_OP, torrents);
-			}
-
-		} catch (Throwable tt) {
-			tt.printStackTrace();
-		}
-	}
-
-	private Map constructJSTorrentProgress(byte[] infohash, String name,
-			int percent, long _eta) {
-		String hash = infohash == null ? "<null>" : Base32.encode(infohash);
-		String eta = formatETA(_eta);
-
-		Map torrent = new HashMap();
-		torrent.put("hash", hash);
-		torrent.put("name", name);
-		torrent.put("percent", new Long(percent));
-		torrent.put("eta", eta);
-
-		return torrent;
-	}
-
-	private Map constructJSGlobalProgress(int percent, long _eta) {
-		String eta = formatETA(_eta);
-
-		Map global = new HashMap();
-		global.put("percent", new Long(percent));
-		global.put("eta", eta);
-
-		return global;
-	}
-
-	private String formatETA(long eta) {
-		if (eta == INFINITE_ETA) {
-			return "";
-		} else if (eta == STOPPED_ETA) {
-			return "x";
-		} else if (eta == ERROR_ETA) {
-			return "e";
-		}
-
-		return TimeFormatter.format( eta );
-	}
-
-	private static class IndividualProgress
-	{
-		private final byte[] infohash;
-
-		private final String name;
-
-		private final int percent;
-
-		private final long eta;
-
-		private IndividualProgress(byte[] _infohash, String _name, int _percent,
-				long _eta) {
-			this.infohash = _infohash;
-			this.name = _name;
-			this.percent = _percent;
-			this.eta = _eta;
-		}
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/browser/msg/MessageDispatcherSWT.java b/com/aelitis/azureus/ui/swt/browser/msg/MessageDispatcherSWT.java
index 92e6721..ca1c647 100644
--- a/com/aelitis/azureus/ui/swt/browser/msg/MessageDispatcherSWT.java
+++ b/com/aelitis/azureus/ui/swt/browser/msg/MessageDispatcherSWT.java
@@ -51,8 +51,6 @@ import com.aelitis.azureus.util.UrlFilter;
  * 
  * @author dharkness
  * @created Jul 18, 2006
- * 
- * @todo Remove "extends MessageDispatcher" after EMP for 3100 is out
  */
 public class MessageDispatcherSWT
 	implements StatusTextListener, TitleListener, BrowserMessageDispatcher
@@ -126,13 +124,6 @@ public class MessageDispatcherSWT
 		}
 	}
 
-	// @see com.aelitis.azureus.ui.swt.browser.msg.MessageDispatcher#addListener(com.aelitis.azureus.ui.swt.browser.msg.MessageListener)
-	public void addListener(MessageListener listener) {
-		if (listener instanceof BrowserMessageListener) {
-			addListener((BrowserMessageListener) listener);
-		}
-	}
-
 	/**
 	 * Deregisters the listener with the given ID.
 	 * 
@@ -169,11 +160,17 @@ public class MessageDispatcherSWT
 	 * @see org.eclipse.swt.browser.StatusTextListener#changed(org.eclipse.swt.browser.StatusTextEvent)
 	 */
 	public void changed(StatusTextEvent event) {
+		if (event.widget.isDisposed() || ((Browser) event.widget).getShell().isDisposed()) {
+			return;
+		}
 		processIncomingMessage(event.text, ((Browser) event.widget).getUrl());
 	}
 
 	// @see org.eclipse.swt.browser.TitleListener#changed(org.eclipse.swt.browser.TitleEvent)
 	public void changed(TitleEvent event) {
+		if (event.widget.isDisposed() || ((Browser) event.widget).getShell().isDisposed()) {
+			return;
+		}
 		processIncomingMessage(event.title, ((Browser) event.widget).getUrl());
 	}
 
@@ -223,6 +220,9 @@ public class MessageDispatcherSWT
 
 		// handle messages for dispatcher and context regardless of sequence number
 		String listenerId = message.getListenerId();
+		if ("lightbox-browser".equals(listenerId)) {
+			listenerId = "display";
+		}
 		if (LISTENER_ID.equals(listenerId)) {
 			handleMessage(message);
 		} else {
@@ -258,8 +258,7 @@ public class MessageDispatcherSWT
 	public boolean isValidSequence(BrowserMessage message) {
 		int sequence = message.getSequence();
 		if (sequence < 0) {
-			Debug.outNoStack("Invalid sequence number: " + sequence);
-			return false;
+			return true;
 		}
 
 		if (sequence <= lastSequence) {
diff --git a/com/aelitis/azureus/ui/swt/browser/msg/MessageListener.java b/com/aelitis/azureus/ui/swt/browser/msg/MessageListener.java
deleted file mode 100644
index 47e9d7a..0000000
--- a/com/aelitis/azureus/ui/swt/browser/msg/MessageListener.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Created on Jun 29, 2006 10:16:26 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.ui.swt.browser.msg;
-
-import com.aelitis.azureus.core.messenger.browser.listeners.BrowserMessageListener;
-
-/**
- * DO NOT USE
- *
- */
-public interface MessageListener extends BrowserMessageListener
-{
-}
diff --git a/com/aelitis/azureus/ui/swt/buddy/VuzeBuddySWT.java b/com/aelitis/azureus/ui/swt/buddy/VuzeBuddySWT.java
deleted file mode 100644
index 8f005a5..0000000
--- a/com/aelitis/azureus/ui/swt/buddy/VuzeBuddySWT.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Created on Apr 14, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.ui.swt.buddy;
-
-import org.eclipse.swt.graphics.Image;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-
-/**
- * @author TuxPaper
- * @created Apr 14, 2008
- *
- */
-public interface VuzeBuddySWT
-	extends VuzeBuddy
-{
-	/**
-	 * After using, please {@link #releaseAvatarImage(Image)}
-	 * @return
-	 *
-	 * @since 4.0.0.5
-	 */
-	Image getAvatarImage();
-
-	void setAvatarImage(Image avatarImage);
-
-	/**
-	 * @param image
-	 *
-	 * @since 4.0.0.5
-	 */
-	void releaseAvatarImage(Image image);
-}
diff --git a/com/aelitis/azureus/ui/swt/buddy/chat/impl/ChatWindow.java b/com/aelitis/azureus/ui/swt/buddy/chat/impl/ChatWindow.java
deleted file mode 100644
index 3621ed2..0000000
--- a/com/aelitis/azureus/ui/swt/buddy/chat/impl/ChatWindow.java
+++ /dev/null
@@ -1,528 +0,0 @@
-package com.aelitis.azureus.ui.swt.buddy.chat.impl;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.layout.*;
-import org.eclipse.swt.program.Program;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.core3.util.SystemTime;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.chat.*;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-import com.aelitis.azureus.ui.swt.views.skin.AvatarWidget;
-
-public class ChatWindow implements DiscussionListener {
-	
-	private static List chatWindows =  new ArrayList();
-	
-	AvatarWidget avatar;
-	Chat chat;
-	ChatDiscussion discussion;
-	
-	Display display;
-
-	Shell shell;
-	Color white;
-	
-	ScrolledComposite messagesHolder;
-	Composite messages;
-	
-	Text input;
-	
-	Listener moveListener;
-	
-	Font textFont;
-	Font nameFont;
-	Font timeFont;
-	
-	PaintListener myNameHighligther;
-	PaintListener friendNameHighlighter;
-	
-	static DateFormat dateFormater = new SimpleDateFormat("hh:mm a");
-	
-	static final int border = 5;
-	static final int spacing = 5;
-	
-	Listener linkListener;
-	
-	String lastSender;
-	
-	public ChatWindow(AvatarWidget _avatar,Chat _chat,ChatDiscussion _discussion) {
-		this.avatar = _avatar;
-		this.chat = _chat;
-		this.discussion = _discussion;
-		
-		synchronized(chatWindows) {
-			chatWindows.add(this);
-		}
-		
-		linkListener = new Listener() {
-			public void handleEvent(Event e) {
-				String text = e.text;
-				//System.out.println(text);
-				//TODO Gudy / Tux launch utily?
-				Program.launch(text);
-			}
-		};
-		
-		Control avatarControl = avatar.getControl();
-		display = avatarControl.getDisplay();
-		
-		
-		shell = new Shell(avatar.getControl().getShell(),SWT.CLOSE | SWT.TOOL );
-		shell.setText(MessageText.getString("v3.buddy.menu.chat"));
-		
-		shell.addListener(SWT.Close, new Listener() {
-			public void handleEvent(Event e) {
-					close();
-			}
-		});
-		
-		shell.addListener(SWT.Traverse, new Listener() {
-			public void handleEvent(Event e) {
-				if (e.detail == SWT.TRAVERSE_ESCAPE) {
-					e.doit = false;
-					hide();
-				}
-			}
-		});
-		
-		FillLayout fillLayout = new FillLayout();
-		fillLayout.marginHeight = 3;
-		fillLayout.marginWidth = 3;
-		shell.setLayout(fillLayout);
-		
-		final Composite mainPanel = new Composite(shell,SWT.NONE);
-		
-		FormLayout formLayout = new FormLayout();
-		formLayout.marginBottom = 0;
-		formLayout.marginTop = 0;
-		formLayout.marginLeft = 0;
-		formLayout.marginRight = 0;
-		
-		mainPanel.setLayout(formLayout);
-		mainPanel.setBackgroundMode(SWT.INHERIT_DEFAULT);
-		
-		myNameHighligther = new PaintListener() {
-			public void paintControl(PaintEvent e) {
-				Label label = (Label) e.widget;
-				String text = (String)label.getData("text");
-				if(text != null) {
-					Point p = label.getSize();
-					try { e.gc.setTextAntialias(SWT.ON); e.gc.setAntialias(SWT.ON);} catch(Exception e2) {}
-					e.gc.setForeground(ColorCache.getColor(display, 93,93,93));
-					e.gc.setBackground(ColorCache.getColor(display, 208,208,208));
-					e.gc.fillRoundRectangle(0, 0, p.x, p.y, 12, 12);
-					e.gc.drawText(text, 4, 0);
-				}
-			}
-		};
-		
-		friendNameHighlighter = new PaintListener() {
-			public void paintControl(PaintEvent e) {
-				Label label = (Label) e.widget;
-				String text = (String)label.getData("text");
-				if(text != null) {
-					Point p = label.getSize();
-					try { e.gc.setTextAntialias(SWT.ON); e.gc.setAntialias(SWT.ON);} catch(Exception e2) {}
-					e.gc.setForeground(ColorCache.getColor(display, 93,93,93));
-					e.gc.setBackground(ColorCache.getColor(display, 192,204,220));
-					e.gc.fillRoundRectangle(0, 0, p.x, p.y, 12, 12);
-					e.gc.drawText(text, 4, 0);
-				}
-			}
-		};
-		
-		FontData[] fDatas = shell.getFont().getFontData();
-		for(int i = 0 ; i < fDatas.length ; i++) {
-			if(Constants.isOSX) {
-				fDatas[i].setHeight(12);
-			} else {
-				fDatas[i].setHeight(10);
-			}
-		}
-		textFont = new Font(display,fDatas);
-		
-		for(int i = 0 ; i < fDatas.length ; i++) {
-			if(Constants.isOSX) {
-				fDatas[i].setHeight(9);
-			} else {
-				fDatas[i].setHeight(7);
-			}
-		}
-		timeFont = new Font(display,fDatas);
-		
-		for(int i = 0 ; i < fDatas.length ; i++) {
-			if(Constants.isOSX) {
-				fDatas[i].setHeight(14);
-			} else {
-				fDatas[i].setHeight(12);
-			}
-			fDatas[i].setStyle(SWT.BOLD);
-		}
-		nameFont = new Font(display,fDatas);
-		
-		
-		
-		
-		FormData data;
-			
-		Canvas avatarPicture = new Canvas(mainPanel,SWT.NONE);
-		avatarPicture.addPaintListener(new PaintListener() {
-			public void paintControl(PaintEvent e) {
-				Image avatarImage = avatar.getVuzeBuddy().getAvatarImage();
-				if (avatarImage != null) {
-					Rectangle size = avatarImage.getBounds();
-					e.gc.drawImage(avatarImage, 0, 0, size.width,size.height,0,0,30,30);
-				}
-				avatar.getVuzeBuddy().releaseAvatarImage(avatarImage);
-			}
-		});
-		
-		data = new FormData();
-		data.width = 30;
-		data.height = 30;
-		data.left = new FormAttachment(0,border);
-		data.top = new FormAttachment(0,border);
-		
-		avatarPicture.setLayoutData(data);
-		
-		Label avatarName = new Label(mainPanel,SWT.NONE);
-//		avatarName.setBackground(mainPanel.getBackground());
-		avatarName.setFont(nameFont);
-		avatarName.setText(avatar.getVuzeBuddy().getDisplayName());
-		data = new FormData();
-		data.left = new FormAttachment(avatarPicture,spacing);
-		data.top = new FormAttachment(avatarPicture,-6,SWT.CENTER);
-		data.right = new FormAttachment(100,-5);
-		avatarName.setLayoutData(data);
-		
-		/*Label header = new Label(shell,SWT.NONE);
-		header.setBackground(ColorCache.getColor(display, 72,72,72));
-		
-		data = new FormData();
-		data.left = new FormAttachment(0,0);
-		data.right = new FormAttachment(100,0);
-		data.top = new FormAttachment(0,0);
-		data.bottom = new FormAttachment(0,30);
-		
-		header.setLayoutData(data);*/
-		
-		messagesHolder = new ScrolledComposite(mainPanel,SWT.BORDER | SWT.V_SCROLL);
-		messagesHolder.setBackground(mainPanel.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
-		messagesHolder.setAlwaysShowScrollBars(true);
-		messagesHolder.setExpandHorizontal(true);
-		messagesHolder.setExpandVertical(true);
-		
-		
-		
-		messages = new Composite(messagesHolder,SWT.NONE);
-		messages.setBackground(messagesHolder.getBackground());
-		GridLayout messagesLayout = new GridLayout();
-		messagesLayout.verticalSpacing=5;
-		messages.setLayout(messagesLayout);
-		messagesHolder.setContent(messages);
-		
-		List chatMessages = discussion.getAllMessages();
-		for(int i = 0 ; i < chatMessages.size() ; i++) {
-			ChatMessage cm = (ChatMessage)chatMessages.get(i);
-			cm.setRendered();
-			renderMessage( cm );
-		}
-		
-		discussion.setListener(new DiscussionListener() {
-			public void newMessage(final ChatMessage message) {
-				message.setRendered();
-				if(!display.isDisposed()) {
-					display.asyncExec(new Runnable() {
-						public void run() {
-							if(!messages.isDisposed()) {
-								renderMessage(message);
-							}
-						}
-					});
-				}
-			}
-		});
-		
-		input = new Text(mainPanel,SWT.WRAP);
-		input.setBackground(messagesHolder.getBackground());
-		input.setTextLimit(256);
-		input.setFont(textFont);
-
-		input.addListener(SWT.KeyUp, new Listener() {
-			public void handleEvent(Event e) {
-				if(e.keyCode == 13) {
-					String text = input.getText().trim();
-					if(text.length() > 0) {
-						chat.sendMessage(avatar.getVuzeBuddy(), text);	
-					}
-					input.setText("");
-				}
-			}	
-		});
-		input.addListener(SWT.Modify, new Listener() {
-			public void handleEvent(Event e) {
-				mainPanel.layout();	
-			}
-		});
-		
-		data = new FormData();
-		data.left = new FormAttachment(0,border);
-		data.right = new FormAttachment(100,-border);
-		data.bottom = new FormAttachment(100,-border);
-		input.setLayoutData(data);
-		
-		data = new FormData();
-		data.left = new FormAttachment(0,border);
-		data.right = new FormAttachment(100,-border);
-		data.top = new FormAttachment(avatarPicture,spacing);
-		data.bottom = new FormAttachment(input,-border);
-		messagesHolder.setLayoutData(data);
-		
-		shell.setSize(250,300);
-		
-		setPosition();
-		
-//		moveListener =  new Listener() {
-//			public void handleEvent(Event arg0) {
-//				setPosition();
-//			}
-//		};
-//		avatarControl.getShell().addListener(SWT.Move,moveListener);
-		
-		input.setFocus();
-		
-		
-		
-		if(avatar.getVuzeBuddy().getVersion() < VuzeBuddy.VERSION_CHAT) {
-			renderSystemMessage(MessageText.getString("v3.chat.wrongversion",new String[] {avatar.getVuzeBuddy().getDisplayName()}));
-			input.setEnabled(false);
-		} else {
-			if(!avatar.getVuzeBuddy().isOnline(true)) {
-				renderSystemMessage(MessageText.getString("v3.chat.offline",new String[] {avatar.getVuzeBuddy().getDisplayName()}));
-			}
-		}
-
-//		hideAllOthers();
-		shell.open();
-		
-		//Need to post to display in order to NOT catch the mouse up event which would hide this window...
-		display.asyncExec(new Runnable() {
-			public void run() {
-				avatar.getControl().redraw();
-			}
-		});
-		
-	}
-	
-	private void renderSystemMessage(String message) {
-		Composite messageHolder = new Composite(messages,SWT.NONE);
-		messageHolder.setBackground(ColorCache.getColor(display, 244,238,188));
-		FillLayout layout = new FillLayout();
-		layout.marginHeight = 3;
-		layout.marginWidth = 5;	
-		messageHolder.setLayout(layout);
-		
-
-		Label text = new Label(messageHolder,SWT.WRAP);
-		text.setBackground(ColorCache.getColor(display, 244,238,188));
-		text.setText(message);
-		
-		messageHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		messages.layout();
-
-	}
-	
-	private void renderMessage(ChatMessage message) {
-		Composite messageHolder = new Composite(messages,SWT.NONE);
-		messageHolder.setBackgroundMode(SWT.INHERIT_FORCE);
-		messageHolder.setBackground(messagesHolder.getBackground());
-		messageHolder.setLayout(new FormLayout());
-		FormData data;
-		
-		Label name = null;
-		Label time_lab = new Label(messageHolder,SWT.NONE);
-		
-		String sender = message.getSender();
-		if(sender != null) {
-			if(!sender.equals(lastSender)) {
-				name = new Label(messageHolder,SWT.NONE);
-				name.setData("text",message.getSender());
-				data = new FormData();
-				data.left = new FormAttachment(0,0);
-				data.right = new FormAttachment(100,0);
-				name.setLayoutData(data);
-				if(message.isMe()) {
-					name.addPaintListener(myNameHighligther);
-				} else {
-					name.addPaintListener(friendNameHighlighter);
-				}
-			}
-			lastSender = sender;
-		}
-		
-		long time = message.getOriginatorTimestamp();
-		
-		if ( time > SystemTime.getCurrentTime()){
-		
-			 time = SystemTime.getCurrentTime();
-		}
-		
-		time_lab.setText(dateFormater.format(new Date(time)));
-		data = new FormData();
-		if(name != null) {
-			data.top = new FormAttachment(name,1);
-		}
-		data.right = new FormAttachment(100,0);
-		time_lab.setLayoutData(data);
-		time_lab.setFont(timeFont);
-		
-		Link text = new Link(messageHolder,SWT.WRAP);
-		text.setBackground(messageHolder.getBackground());
-		text.setForeground(ColorCache.getColor(display,27,27,27));
-		text.setFont(textFont);
-		String msg = message.getMessage();
-		msg = msg.replaceAll("(?i)((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\]))", "<a href=\"mailto:$1\">$0</a>");
-		msg = msg.replaceAll("(?i)\\b(https?://[^\\s]*?)(\\s|\\]|>|\\z)", "<a href=\"$1\">$0</a>");
-		text.setText(msg);
-		data = new FormData();
-		data.left = new FormAttachment(0,3);
-		data.right = new FormAttachment(time_lab,-3);
-		if(name != null) {
-			data.top = new FormAttachment(name,0);
-		}
-		text.setLayoutData(data);
-		text.addListener(SWT.Selection, linkListener);
-		
-		messageHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		messages.layout();
-		
-		Rectangle r = messagesHolder.getClientArea();
-		messagesHolder.setMinSize(messages.computeSize(r.width, SWT.DEFAULT));
-		
-		messagesHolder.getVerticalBar().setSelection(messagesHolder.getVerticalBar().getMaximum());
-		messagesHolder.layout();	
-		
-		if(shell.isVisible()) {
-			discussion.clearNewMessages();
-		}
-		
-	}
-	
-	public void close() {
-		discussion.clearAllMessages();
-		discussion.setListener( null );
-//		avatar.getControl().getShell().removeListener(SWT.Move, moveListener);
-		shell.dispose();
-		if(textFont != null && !textFont.isDisposed()) {
-			textFont.dispose();
-		}
-		if(nameFont != null && !nameFont.isDisposed()) {
-			nameFont.dispose();
-		}
-		if(timeFont != null && !timeFont.isDisposed()) {
-			timeFont.dispose();
-		}
-		synchronized(chatWindows) {
-			chatWindows.remove(ChatWindow.this);
-		}
-		avatar.getControl().redraw();
-	}
-	
-	public void setPosition() {
-		Control avatarControl = avatar.getControl();
-		if(avatar.isFullyVisible() && !shell.isDisposed()) {
-			Point shellPosition = avatarControl.toDisplay(0,0);
-			shellPosition.y -= 300;
-			int displayWidth = display.getBounds().width;
-			if(shellPosition.x + 250 > displayWidth) {
-				shellPosition.x = displayWidth - 250;
-			}
-			shell.setLocation(shellPosition);
-		} else {
-			hide();
-		}
-	}
-	
-	public void newMessage(final ChatMessage message) {
-		if(!display.isDisposed()) {
-			message.setRendered();
-			display.asyncExec(new Runnable() {
-				public void run() {
-					renderMessage(message);
-					avatar.getControl().redraw();
-				}
-			});
-		}
-		
-	}
-	
-	public boolean isDisposed() {
-		if(shell != null) {
-			return shell.isDisposed();
-		} else {
-			return true;
-		}
-	}
-	
-	public boolean isVisible() {
-		if(!shell.isDisposed()) {
-			return shell.isVisible();
-		}
-		return false;
-	}
-	
-	public void show() {
-		if(!shell.isDisposed()) {
-//			hideAllOthers();
-			setPosition();
-			shell.setVisible(true);
-			input.setFocus();
-			discussion.clearNewMessages();
-			avatar.getControl().redraw();
-		}
-	}
-	
-	public void hide() {
-		if(discussion.getNbMessages() == 0) {
-			close();
-		}
-		if(!shell.isDisposed()) {
-			shell.setVisible(false);
-			Color gray = display.getSystemColor(SWT.COLOR_DARK_GRAY);
-			Control[] controls = messages.getChildren();
-			for(int i = 0 ; i < controls.length ; i++) {
-				Control[] children = ((Composite)controls[i]).getChildren();
-				for(int j = 0 ; j < children.length ; j++) {
-					children[j].setForeground(gray);
-				}
-			}
-		}
-	}
-	
-	public void hideAllOthers() {
-		synchronized (chatWindows) {
-			for(int i = 0 ; i < chatWindows.size() ; i++) {
-				ChatWindow chatWindow = (ChatWindow) chatWindows.get(i);
-				if(chatWindow != this && !chatWindow.isDisposed()) {
-					chatWindow.hide();
-				}
-			}
-		}
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/buddy/chat/impl/MessageNotificationWindow.java b/com/aelitis/azureus/ui/swt/buddy/chat/impl/MessageNotificationWindow.java
deleted file mode 100644
index fe57da1..0000000
--- a/com/aelitis/azureus/ui/swt/buddy/chat/impl/MessageNotificationWindow.java
+++ /dev/null
@@ -1,213 +0,0 @@
-package com.aelitis.azureus.ui.swt.buddy.chat.impl;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.util.AEThread2;
-import org.gudy.azureus2.core3.util.Constants;
-
-import com.aelitis.azureus.buddy.chat.ChatMessage;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.views.skin.AvatarWidget;
-
-public class MessageNotificationWindow {
-	
-	private static final int initialAlpha = 230;
-	
-	public static int nbOpen = 0;
-	public static int currentOffset = 0;
-	
-	public MessageNotificationWindow(final AvatarWidget avatar,final ChatMessage message) {
-		final org.eclipse.swt.widgets.Display display = avatar.getControl().getDisplay();
-		
-		final Shell shell = new Shell(display,SWT.NO_TRIM |  SWT.ON_TOP);
-		
-		Image background = ImageLoader.getInstance().getImage("chatNotification");
-		final Region region = new Region();
-		final ImageData imageData = background.getImageData();
-		if (imageData.alphaData != null) {
-			Rectangle pixel = new Rectangle(0, 0, 1, 1);
-			for (int y = 0; y < imageData.height; y++) {
-				for (int x = 0; x < imageData.width; x++) {
-					if (imageData.getAlpha(x, y) == 255) {
-						pixel.x = imageData.x + x;
-						pixel.y = imageData.y + y;
-						region.add(pixel);
-					} 
-				}
-			}
-		} else {
-			ImageData mask = imageData.getTransparencyMask();
-			Rectangle pixel = new Rectangle(0, 0, 1, 1);
-			for (int y = 0; y < mask.height; y++) {
-				for (int x = 0; x < mask.width; x++) {
-					if (mask.getPixel(x, y) != 0) {
-						pixel.x = imageData.x + x;
-						pixel.y = imageData.y + y;
-						region.add(pixel);
-					}
-				}
-			}
-		}
-		shell.setRegion(region);
-		shell.setBackgroundImage(background);
-		shell.setBackgroundMode(SWT.INHERIT_FORCE);
-		
-		shell.setLayout(new FormLayout());
-		FormData data;
-		
-		Canvas image = new Canvas(shell,SWT.NONE);
-		image.addPaintListener(new PaintListener() {
-			public void paintControl(PaintEvent e) {
-				Image avatarImage = avatar.getVuzeBuddy().getAvatarImage();
-				if (avatarImage != null) {
-					e.gc.drawImage(avatarImage, 0, 0, 40, 40, 0, 0, 30, 30);
-				}
-				avatar.getVuzeBuddy().releaseAvatarImage(avatarImage);
-			}
-		});
-		
-		
-		
-		Label name = new Label(shell,SWT.NONE);
-		name.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
-		name.setText(message.getSender());
-		
-		FontData[] fDatas = name.getFont().getFontData();
-		for(int i = 0 ; i < fDatas.length ; i++) {
-			if(Constants.isOSX) {
-				fDatas[i].setHeight(12);
-			} else {
-				fDatas[i].setHeight(10);
-			}
-			fDatas[i].setStyle(SWT.BOLD);
-		}
-		final Font nameFont = new Font(display,fDatas);
-		name.setFont(nameFont);
-		
-		Label text = new Label(shell,SWT.NONE);
-		text.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
-		text.setText(message.getMessage());
-		
-		data = new FormData();
-		data.left = new FormAttachment(0,12);
-		data.top = new FormAttachment(0,10);
-		data.width = 30;
-		data.height = 30;
-		image.setLayoutData(data);
-		
-		data = new FormData();
-		data.left = new FormAttachment(image,5);
-		data.right = new FormAttachment(100,-5);
-		data.top = new FormAttachment(0,10);
-		name.setLayoutData(data);
-		
-		data = new FormData();
-		data.left = new FormAttachment(image,5);
-		data.top = new FormAttachment(name,1);
-		data.right = new FormAttachment(100,-5);
-		data.bottom = new FormAttachment(image,0,SWT.BOTTOM);
-		text.setLayoutData(data);
-		
-		Listener mouseUpListener = new Listener() {
-			public void handleEvent(Event arg0) {
-				avatar.doChatClicked(true);
-				avatar.getControl().getShell().setVisible(true);
-				avatar.getControl().getShell().setActive();
-				shell.dispose();
-				region.dispose();
-				nameFont.dispose();
-				nbOpen--;
-				if(nbOpen == 0) {
-					currentOffset = 0;
-				}
-			}
-		};
-		
-		shell.addListener(SWT.MouseUp, mouseUpListener);
-		name.addListener(SWT.MouseUp, mouseUpListener);
-		image.addListener(SWT.MouseUp, mouseUpListener);
-		text.addListener(SWT.MouseUp, mouseUpListener);
-		
-		AEThread2 closer = new AEThread2("notification closer",true) {
-			public void run() {
-				try {
-					Thread.sleep(5000);
-
-					for(int alpha = initialAlpha ; alpha > 0 ; alpha-=10) {
-						
-						final int _alpha = alpha;
-						
-						if(!display.isDisposed()) {
-							display.asyncExec(new Runnable() {
-								public void run() {
-									if(!shell.isDisposed()) {
-										try {
-											shell.setAlpha(_alpha);
-										} catch(Throwable t) {
-											//Ignore
-										}
-									}
-								};
-							});
-						}
-						
-						Thread.sleep(50);
-					}
-					
-					
-				} catch (Throwable t) {
-					//Do nothing
-				} finally {
-					if(!display.isDisposed()) {
-						display.asyncExec(new Runnable() {
-							public void run() {
-								if(!shell.isDisposed()) {
-									shell.dispose();
-									region.dispose();
-									nameFont.dispose();
-									nbOpen--;
-									if(nbOpen == 0) {
-										currentOffset = 0;
-									}
-								}
-							};
-						});
-					}
-				}
-			}
-		};
-		
-		closer.start();
-		
-		
-		Rectangle displayArea = display.getBounds();
-		shell.setLocation(displayArea.width - imageData.width - 50 ,100 + (imageData.height+20) * currentOffset);
-		shell.setSize(imageData.x + imageData.width, imageData.y + imageData.height);
-		
-		try {
-			shell.setAlpha(initialAlpha);
-		} catch (Throwable t) {
-			//Do nothing
-		}
-		
-		shell.addDisposeListener(new DisposeListener() {
-			public void widgetDisposed(DisposeEvent e) {
-				ImageLoader.getInstance().releaseImage("chatNotification");
-			}
-		});
-		
-		shell.open();
-		shell.setActive();
-		//shell.forceActive();
-		nbOpen++;
-		currentOffset++;
-	}
-	
-
-}
diff --git a/com/aelitis/azureus/ui/swt/buddy/impl/VuzeBuddyFakeSWTImpl.java b/com/aelitis/azureus/ui/swt/buddy/impl/VuzeBuddyFakeSWTImpl.java
deleted file mode 100644
index 3e363a9..0000000
--- a/com/aelitis/azureus/ui/swt/buddy/impl/VuzeBuddyFakeSWTImpl.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Created on Jun 18, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
- 
-package com.aelitis.azureus.ui.swt.buddy.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author TuxPaper
- * @created Jun 18, 2008
- *
- */
-public class VuzeBuddyFakeSWTImpl
-	extends VuzeBuddySWTImpl
-{
-	private List pks = new ArrayList();
-	
-	
-	/**
-	 * @param map
-	 */
-	public VuzeBuddyFakeSWTImpl(Map map) {
-		loadFromMap(map);
-	}
-
-	public void addPublicKey(String pk) {
-		if (!pks.contains(pk)) {
-			pks.add(pk);
-		}
-	}
-	
-	// @see com.aelitis.azureus.buddy.impl.VuzeBuddyImpl#removePublicKey(java.lang.String)
-	public void removePublicKey(String pk) {
-		pks.remove(pk);
-	}
-	
-	// @see com.aelitis.azureus.buddy.impl.VuzeBuddyImpl#getPublicKeys()
-	public String[] getPublicKeys() {
-		return (String[]) pks.toArray(new String[pks.size()]);
-	}
-	
-	public void setDisplayName(String displayName) {
-		// like super, except no trigger
-		if (displayName == null) {
-			displayName = "";
-		}
-		if (displayName.equals(this.displayName)){
-			return;
-		}
-		this.displayName = displayName;
-	}
-	
-	public String toDebugString() {
-		return "Fake" + super.toDebugString(); 
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/buddy/impl/VuzeBuddySWTImpl.java b/com/aelitis/azureus/ui/swt/buddy/impl/VuzeBuddySWTImpl.java
deleted file mode 100644
index cc0809d..0000000
--- a/com/aelitis/azureus/ui/swt/buddy/impl/VuzeBuddySWTImpl.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * Created on Apr 14, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.ui.swt.buddy.impl;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.Display;
-
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.ui.swt.Utils;
-
-import com.aelitis.azureus.buddy.impl.VuzeBuddyImpl;
-import com.aelitis.azureus.ui.swt.buddy.VuzeBuddySWT;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-
-/**
- * @author TuxPaper
- * @created Apr 14, 2008
- *
- */
-public class VuzeBuddySWTImpl
-	extends VuzeBuddyImpl
-	implements VuzeBuddySWT
-{
-	private Image avatarImage;
-	
-	private boolean needsImageRebuilt = true;
-
-	private String avatarImageRefId;
-
-	/**
-	 * 
-	 */
-	public VuzeBuddySWTImpl(String publicKey) {
-		super(publicKey);
-	}
-
-	public VuzeBuddySWTImpl() {
-	}
-
-	public void setAvatar(byte[] avatar) {
-		needsImageRebuilt = true;
-
-		super.setAvatar(avatar);
-	}
-
-	public Image getAvatarImage() {
-		ImageLoader imageLoader = ImageLoader.getInstance();
-		if (needsImageRebuilt || !imageLoader.imageExists(avatarImageRefId)) {
-
-			boolean useDefault = true;
-
-			byte[] avatarBytes = getAvatar();
-			if (avatarBytes != null) {
-				try {
-  				Display display = Utils.getDisplay();
-  				if (display == null) {
-  					return null;
-  				}
-  				InputStream is = new ByteArrayInputStream(avatarBytes);
-  				Image bigAvatarImage = new Image(display, is);
-  				avatarImage = new Image(display, 40, 40);
-  				GC gc = new GC(avatarImage);
-  				try {
-  					Rectangle bounds = bigAvatarImage.getBounds();
-  					try {
-  						gc.setInterpolation(SWT.HIGH);
-  					} catch (Exception e) {
-  					}
-  					gc.drawImage(bigAvatarImage, 0, 0, bounds.width, bounds.height, 0, 0,
-  							40, 40);
-  				} finally {
-  					gc.dispose();
-  				}
-  				bigAvatarImage.dispose();
-  				avatarImageRefId = "image.buddy.avatar." + getLoginID();
-  				imageLoader.addImage(avatarImageRefId, avatarImage);
-  				useDefault = false;
-				} catch (Exception e) {
-				}
-			}
-
-			if (useDefault) {
-				try {
-					avatarImageRefId = "image.buddy.default.avatar"; 
-					avatarImage = imageLoader.getImage(avatarImageRefId);
-				} catch (Exception e) {
-					imageLoader.releaseImage(avatarImageRefId);
-					avatarImageRefId = null;
-					avatarImage = null;
-				}
-			}
-			
-			needsImageRebuilt = false;
-		} else {
-			avatarImage = imageLoader.getImage(avatarImageRefId);
-		}
-		
-		return avatarImage;
-	}
-	
-	public void releaseAvatarImage(Image image) {
-		if (image == avatarImage && avatarImageRefId != null) {
-			ImageLoader imageLoader = ImageLoader.getInstance();
-			imageLoader.releaseImage(avatarImageRefId);
-		}
-	}
-
-	public void setAvatarImage(final Image avatarImage) {
-		releaseAvatarImage(this.avatarImage);
-		
-		this.avatarImage = avatarImage;
-
-		if (avatarImage != null) {
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					org.eclipse.swt.graphics.ImageLoader loader = new org.eclipse.swt.graphics.ImageLoader();
-					ByteArrayOutputStream os = new ByteArrayOutputStream();
-					loader.data = new ImageData[] {
-						avatarImage.getImageData()
-					};
-					loader.save(os, SWT.IMAGE_PNG);
-					VuzeBuddySWTImpl.super.setAvatar(os.toByteArray());
-				}
-			});
-		}
-	}
-
-	// @see com.aelitis.azureus.buddy.impl.VuzeBuddyImpl#toDebugString()
-	public String toDebugString() {
-		return "SWT" + super.toDebugString();
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/buddy/impl/VuzeBuddyUtils.java b/com/aelitis/azureus/ui/swt/buddy/impl/VuzeBuddyUtils.java
deleted file mode 100644
index 84b83ab..0000000
--- a/com/aelitis/azureus/ui/swt/buddy/impl/VuzeBuddyUtils.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Created on Apr 14, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.ui.swt.buddy.impl;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-
-/**
- * @author TuxPaper
- * @created Apr 14, 2008
- *
- */
-public class VuzeBuddyUtils
-{
-
-	/**
-	 * Creates a random buddy.  Not actually stored anywhere..
-	 * 
-	 * 
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-
-	public static VuzeBuddy createRandomBuddy() {
-		int x = (int) (Math.random() * 10000);
-		VuzeBuddySWTImpl buddy = new VuzeBuddySWTImpl();
-		buddy.setLoginID("Login" + x);
-		buddy.setDisplayName("Mr Random " + x);
-		//buddy.setAvatarImage(ImageRepository.getRandomImage());
-
-		VuzeBuddyManager.addBuddy(buddy, false);
-
-		return buddy;
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnAzProduct.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnAzProduct.java
deleted file mode 100644
index 72bfc69..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnAzProduct.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/**
- * 
- */
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.core3.util.SystemTime;
-import org.gudy.azureus2.core3.util.TimeFormatter;
-import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.ui.common.table.impl.TableColumnImpl;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.utils.ContentNetworkUI;
-import com.aelitis.azureus.ui.swt.utils.ContentNetworkUI.ContentNetworkImageLoadedListener;
-import com.aelitis.azureus.util.DataSourceUtils;
-
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Jun 13, 2006
- *
- */
-public class ColumnAzProduct
-	extends CoreTableColumn
-	implements TableCellAddedListener, TableCellToolTipListener,
-	TableCellRefreshListener, TableCellSWTPaintListener
-{
-	private static final String NAME_NOCN = "";
-
-	public static String COLUMN_ID = "AzProduct";
-
-	private static Image imgProductGlobe;
-
-	static {
-		imgProductGlobe = ImageLoader.getInstance().getImage("column.azproduct.globe");
-	}
-
-	/**
-	 * 
-	 */
-	public ColumnAzProduct(String sTableID) {
-		super(COLUMN_ID, ALIGN_CENTER, POSITION_LAST, 40, sTableID);
-		initializeAsGraphic(40);
-	}
-	
-	public ColumnAzProduct(TableColumn column) {
-		super(null, null);
-		column.initialize(ALIGN_CENTER, POSITION_LAST, 40, INTERVAL_GRAPHIC);
-		column.setType(TYPE_GRAPHIC);
-		column.addListeners(this);
-		// cheat.  TODO: Either auto-add (in above method), or provide
-		// access via TableColumn instead of type casting
-		((TableColumnImpl)column).addCellOtherListener("SWTPaint", this);
-	}
-
-	public void fillTableColumnInfo(TableColumnInfo info) {
-		info.addCategories(new String[] {
-			CAT_CONTENT,
-		});
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener#cellAdded(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void cellAdded(TableCell cell) {
-		cell.setMarginWidth(0);
-		cell.setMarginHeight(0);
-	}
-
-	public void cellPaint(GC gc, final TableCellSWT cell) {
-		Object ds = cell.getDataSource();
-
-		Image 			img = imgProductGlobe; 
-		ContentNetwork 	cn 	= null;
-		
-		if ( ds != null ){
-			cn = DataSourceUtils.getContentNetwork(ds);
-	
-			long cnID = cn == null ? -1 : cn.getID();
-	
-			if (cnID > 0) {
-				img = ContentNetworkUI.loadImage(cnID, new ContentNetworkImageLoadedListener() {
-					public void contentNetworkImageLoaded(Long contentNetworkID, Image image, boolean wasReturned) {
-						if (!wasReturned) {
-							cell.invalidate();
-						}
-					}
-				});
-			}
-		}
-		if (img == null) {
-			return;
-		}
-
-		Rectangle imgBounds = img.getBounds();
-		Rectangle cellBounds = cell.getBounds();
-		
-		Rectangle dstBounds;
-		if (imgBounds.height > cellBounds.height) {
-			int w = cellBounds.height * imgBounds.width / imgBounds.height;
-			dstBounds = new Rectangle(imgBounds.x, imgBounds.y, w,
-					cellBounds.height);
-			gc.setAdvanced(true);
-		} else {
-			dstBounds = new Rectangle(imgBounds.x, imgBounds.y, imgBounds.width,
-					imgBounds.height);
-		}
-	  
-		if (cellBounds.width < 60) {
-  		gc.drawImage(img, imgBounds.x, imgBounds.y, imgBounds.width,
-					imgBounds.height, cellBounds.x
-							+ ((cellBounds.width - dstBounds.width) / 2), cellBounds.y
-							+ ((cellBounds.height - dstBounds.height) / 2), dstBounds.width,
-					dstBounds.height);
-		} else {
-			gc.drawImage(img, imgBounds.x, imgBounds.y, imgBounds.width,
-					imgBounds.height, cellBounds.x + 1, cellBounds.y
-							+ ((cellBounds.height - dstBounds.height) / 2), dstBounds.width,
-					dstBounds.height);
-			cellBounds.x += imgBounds.width + 4;
-			cellBounds.width -= imgBounds.width + 4;
-			GCStringPrinter.printString(gc, cn == null ? NAME_NOCN : cn.getName(),
-					cellBounds, true, false, SWT.LEFT);
-		}
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void refresh(final TableCell cell) {
-		Object ds = cell.getDataSource();
-
-		if ( ds != null ){
-			ContentNetwork cn = DataSourceUtils.getContentNetwork(ds);
-	
-			long cnID = cn == null ? -1 : cn.getID();
-			long sortVal = cnID;
-	
-			cell.setSortValue(sortVal);
-		}
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellToolTipListener#cellHover(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void cellHover(TableCell cell) {
-		Object ds = cell.getDataSource();
-
-		if ( ds != null ){
-			
-			ContentNetwork cn = DataSourceUtils.getContentNetwork(ds);
-			
-			cell.setToolTip(cn == null ? null : cn.getName());
-	
-			if (false && Constants.isCVSVersion()) {
-				if (!(ds instanceof DownloadManager)) {
-					return;
-				}
-				DownloadManager dm = (DownloadManager) cell.getDataSource();
-				if (dm == null) {
-					return;
-				}
-	
-				TOTorrent torrent = dm.getTorrent();
-				long refreshOn = PlatformTorrentUtils.getMetaDataRefreshOn(torrent);
-				long diff = (refreshOn - SystemTime.getCurrentTime()) / 1000;
-				cell.setToolTip("Meta data auto refreshes in "
-						+ TimeFormatter.format(diff));
-			}
-		}
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellToolTipListener#cellHoverComplete(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void cellHoverComplete(TableCell cell) {
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnComplete.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnComplete.java
deleted file mode 100644
index aa86129..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnComplete.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import org.eclipse.swt.graphics.Image;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.tables.TableCell;
-import org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener;
-import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
-
-/**
- * @author TuxPaper
- * @created Oct 13, 2006
- *
- */
-public class ColumnComplete
-	extends CoreTableColumn
-	implements TableCellAddedListener, TableCellRefreshListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-	public static String COLUMN_ID = "CompleteIcon";
-
-	private static UISWTGraphicImpl graphicWait;
-
-	private static int width;
-
-	static {
-		Image img = ImageLoader.getInstance().getImage("icon.rate.wait");
-		width = img.getBounds().width;
-		graphicWait = new UISWTGraphicImpl(img);
-	}
-
-	/**
-	 * 
-	 */
-	public ColumnComplete(String sTableID) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_CENTER, width, sTableID);
-		initializeAsGraphic(width);
-		setWidthLimits(width, width);
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener#cellAdded(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void cellAdded(TableCell cell) {
-		cell.setMarginWidth(0);
-		cell.setMarginHeight(0);
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void refresh(TableCell cell) {
-		DownloadManager dm = (DownloadManager) cell.getDataSource();
-		boolean bComplete = dm.isDownloadComplete(false);
-		int sortVal = bComplete ? 0 : 1;
-
-		if (!cell.setSortValue(sortVal) && cell.isValid()) {
-			return;
-		}
-		if (!cell.isShown()) {
-			return;
-		}
-
-		cell.setGraphic(bComplete ? null : graphicWait);
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnInfo.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnInfo.java
deleted file mode 100644
index 7c7c3a2..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnInfo.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Created on Jun 16, 2006 2:41:08 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.views.skin.TorrentListViewsUtils;
-import com.aelitis.azureus.util.DataSourceUtils;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Jun 16, 2006
- *
- * TODO: Implement
- */
-public class ColumnInfo
-	extends CoreTableColumn
-	implements TableCellAddedListener,
-	TableCellMouseListener, TableCellSWTPaintListener, TableCellRefreshListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-	public static final String COLUMN_ID = "Info";
-
-	private static Rectangle imgBounds;
-
-	private static int width = 38;
-
-	private static Image img;
-	
-	private TableRow previousSelection;
-
-	static {
-		img = ImageLoader.getInstance().getImage("icon.info");
-		imgBounds = img.getBounds();
-//		width = boundsRateMe.width;
-	}
-
-	/**
-	 * 
-	 */
-	public ColumnInfo(String sTableID) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_CENTER, width, sTableID);
-		initializeAsGraphic(width);
-	}
-
-	public void fillTableColumnInfo(TableColumnInfo info) {
-		info.addCategories(new String[] {
-			CAT_CONTENT,
-		});
-	}
-
-	public void cellAdded(TableCell cell) {
-		cell.setMarginWidth(0);
-		cell.setMarginHeight(0);
-		if (cell instanceof TableCellSWT) {
-			TOTorrent torrent = DataSourceUtils.getTorrent(cell.getDataSource());
-			if ( torrent != null && PlatformTorrentUtils.isContent(torrent, true)){
-			
-				((TableCellSWT)cell).setCursorID(SWT.CURSOR_HAND);
-			}
-		}
-	}
-
-	public void refresh(TableCell cell) {
-		TOTorrent torrent = DataSourceUtils.getTorrent(cell.getDataSource());
-		
-		cell.setSortValue(torrent != null && PlatformTorrentUtils.isContent(torrent, true)?1:0);
-	}
-	
-	// @see org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener#cellPaint(org.eclipse.swt.graphics.GC, org.gudy.azureus2.ui.swt.views.table.TableCellSWT)
-	public void cellPaint(GC gc, TableCellSWT cell) {
-		TOTorrent torrent = DataSourceUtils.getTorrent(cell.getDataSource());
-		
-		if (PlatformTorrentUtils.isContent(torrent, true)) {
-  		Rectangle cellBounds = cell.getBounds();
-  		if (imgBounds.height > cellBounds.height) {
-				int dstW = (imgBounds.width * (cellBounds.height - 4))
-						/ imgBounds.height;
-				try {
-					gc.setAdvanced(true);
-				} catch (Exception e) {
-					//ignore
-				}
-				gc.drawImage(img, 0, 0, imgBounds.width, imgBounds.height, cellBounds.x
-						+ ((cellBounds.width - dstW) / 2), cellBounds.y + 2, dstW,
-						cellBounds.height - 4);
-			} else {
-    		gc.drawImage(img, cellBounds.x
-    				+ ((cellBounds.width - imgBounds.width) / 2), cellBounds.y + ((cellBounds.height - imgBounds.height) / 2));
-  		}
-		}
-	}
-
-	public void cellMouseTrigger(final TableCellMouseEvent event) {
-		Object ds = event.cell.getDataSource();
-		TOTorrent torrent = null;
-		if (ds instanceof TOTorrent) {
-			torrent = (TOTorrent) ds;
-		} else if (ds instanceof DownloadManager) {
-			torrent = ((DownloadManager) ds).getTorrent();
-		}
-		
-		if( ! PlatformTorrentUtils.isContent(torrent, true)) {
-			return;
-		}
-		
-		// no rating if row isn't selected yet
-		TableRow row = event.cell.getTableRow();
-		if (row != null && !row.isSelected()) {
-			return;
-		}
-		
-		if(row != previousSelection) {
-			previousSelection = row;
-			return;
-		}
-
-
-		// only first button
-		if (event.button == 1 && event.eventType == TableCellMouseEvent.EVENT_MOUSEUP) {
-			try {
-				TorrentListViewsUtils.viewDetailsFromDS(torrent, "info-column");
-			}catch (Exception e) {
-				// TODO: handle exception
-			}
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnIsPrivate.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnIsPrivate.java
deleted file mode 100644
index 7c52dbd..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnIsPrivate.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Created on Jun 29, 2006 10:15:15 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import org.eclipse.swt.graphics.Image;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.tables.TableCell;
-import org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener;
-import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
-
-/**
- * @author TuxPaper
- * @created Jun 29, 2006
- *
- */
-public class ColumnIsPrivate
-	extends CoreTableColumn
-	implements TableCellAddedListener, TableCellRefreshListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-	public static String COLUMN_ID = "IsPrivate";
-
-	private static UISWTGraphicImpl graphicCheck;
-
-	private static int width;
-
-	static {
-		Image img = ImageLoader.getInstance().getImage("image.check");
-		width = img.getBounds().width;
-		graphicCheck = new UISWTGraphicImpl(img);
-	}
-
-	/**
-	 * 
-	 */
-	public ColumnIsPrivate(String sTableID) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_CENTER, width, sTableID);
-		initializeAsGraphic(width);
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener#cellAdded(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void cellAdded(TableCell cell) {
-		cell.setMarginWidth(0);
-		cell.setMarginHeight(0);
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void refresh(TableCell cell) {
-		DownloadManager dm = (DownloadManager) cell.getDataSource();
-		boolean bPrivate = dm.getTorrent().getPrivate();
-		int sortVal = bPrivate ? 0 : 1;
-
-		if (!cell.setSortValue(sortVal) && cell.isValid()) {
-			return;
-		}
-		if (!cell.isShown()) {
-			return;
-		}
-
-		cell.setGraphic(bPrivate ? graphicCheck : null);
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnIsSeeding.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnIsSeeding.java
deleted file mode 100644
index b509924..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnIsSeeding.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Created on Jun 29, 2006 10:16:26 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import org.eclipse.swt.graphics.Image;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.tables.TableCell;
-import org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener;
-import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
-
-/**
- * @author TuxPaper
- * @created Jun 29, 2006
- *
- */
-public class ColumnIsSeeding
-	extends CoreTableColumn
-	implements TableCellAddedListener, TableCellRefreshListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-	public static String COLUMN_ID = "IsSeeding";
-
-	private static UISWTGraphicImpl graphicCheck;
-
-	private static int width;
-
-	static {
-		Image img = ImageLoader.getInstance().getImage("image.check");
-		width = img.getBounds().width;
-		graphicCheck = new UISWTGraphicImpl(img);
-	}
-
-	public ColumnIsSeeding(String sTableID) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_CENTER, width, sTableID);
-		initializeAsGraphic(width);
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener#cellAdded(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void cellAdded(TableCell cell) {
-		cell.setMarginWidth(0);
-		cell.setMarginHeight(0);
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void refresh(TableCell cell) {
-		DownloadManager dm = (DownloadManager) cell.getDataSource();
-		int state = dm.getState();
-		boolean bSeeding = state == DownloadManager.STATE_SEEDING
-				|| ((state == DownloadManager.STATE_CHECKING
-						|| state == DownloadManager.STATE_WAITING || state == DownloadManager.STATE_READY) && dm.getAssumedComplete());
-
-		int sortVal = bSeeding ? 0 : 1;
-
-		if (!cell.setSortValue(sortVal) && cell.isValid()) {
-			return;
-		}
-		if (!cell.isShown()) {
-			return;
-		}
-
-		cell.setGraphic(bSeeding ? graphicCheck : null);
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnMediaStatus.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnMediaStatus.java
deleted file mode 100644
index d1cedb3..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnMediaStatus.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * Copyright (C) 2007 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.tables.TableCell;
-import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
-
-/**
- * @author TuxPaper
- * @created Jan 17, 2007
- *
- */
-public class ColumnMediaStatus
-	extends CoreTableColumn
-	implements TableCellRefreshListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-
-	public static String COLUMN_ID = "MediaStatus";
-
-	/**
-	 * 
-	 */
-	public ColumnMediaStatus(String sTableID) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_LEAD, 120, sTableID);
-	}
-
-	public void refresh(TableCell cell) {
-		String name = null;
-		DownloadManager dm = (DownloadManager) cell.getDataSource();
-
-		// xxx do me
-
-		if (name == null) {
-			name = "";
-		}
-
-		if (!cell.setSortValue(name) && cell.isValid()) {
-			return;
-		}
-
-		if (!cell.isShown()) {
-			return;
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnMediaThumb.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnMediaThumb.java
deleted file mode 100644
index b8cd6fa..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnMediaThumb.java
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Created on Jun 29, 2006 10:13:59 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import java.io.ByteArrayInputStream;
-import java.util.*;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Display;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.torrent.TOTorrentFile;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.ui.swt.ImageRepository;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.plugins.UISWTGraphic;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.ui.common.table.TableCellCore;
-import com.aelitis.azureus.ui.common.table.TableRowCore;
-import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
-import com.aelitis.azureus.ui.swt.columns.utils.ColumnImageClickArea;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-import com.aelitis.azureus.ui.swt.views.skin.TorrentListViewsUtils;
-import com.aelitis.azureus.ui.swt.views.skin.VuzeShareUtils;
-import com.aelitis.azureus.util.DLReferals;
-import com.aelitis.azureus.util.DataSourceUtils;
-import com.aelitis.azureus.util.PlayUtils;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.Graphic;
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Jun 29, 2006
- *
- */
-public class ColumnMediaThumb
-	extends CoreTableColumn
-	implements TableCellAddedListener, TableCellRefreshListener,
-	TableCellDisposeListener, TableCellVisibilityListener,
-	TableCellMouseMoveListener, TableRowMouseListener, TableCellToolTipListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-	public static String COLUMN_ID = "MediaThumb";
-
-	public static final boolean ROW_HOVER = System.getProperty("rowhover", "0").equals(
-			"1");
-
-	private static final boolean SET_ALPHA = false;
-
-	private static final int WIDTH = 60;
-
-	private static final String BTN_PLAY = "play";
-
-	private static final String BTN_DL = "download";
-
-	private static final String BTN_DETAILS = "details";
-
-	private static final String BTN_RUN = "run";
-
-	private static final String BTN_SHARE = "share";
-
-	private static final int BORDER_SIZE = 0;
-
-	private static final int IMG_SIZE = 19;
-
-	private static final int IMG_SIZE_HALF = IMG_SIZE / 2;
-
-	private static final boolean ICONS_BELOW = true;
-
-	private Map mapCellTorrent = new HashMap();
-
-	private final int maxThumbHeight;
-
-	private Image imgPlay;
-
-	private Rectangle imgPlayBounds;
-
-	private List listClickAreas = new ArrayList();
-
-	private ColumnImageClickArea clickAreaRun;
-
-	private ColumnImageClickArea clickAreaPlay;
-
-	private ColumnImageClickArea clickAreaDetails;
-
-	private ColumnImageClickArea clickAreaDL;
-
-	private ColumnImageClickArea clickAreaShare;
-
-	/**
-	 * 
-	 */
-	public ColumnMediaThumb(String sTableID, int maxThumbHeight) {
-		this(sTableID, maxThumbHeight, WIDTH);
-	}
-
-	public ColumnMediaThumb(String sTableID) {
-		this(sTableID, 40, WIDTH);
-	}
-
-	public ColumnMediaThumb(String sTableID, int maxThumbHeight, int WIDTH) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_CENTER, WIDTH, sTableID);
-		this.maxThumbHeight = maxThumbHeight;
-		initializeAsGraphic(WIDTH);
-		setWidthLimits(WIDTH, WIDTH);
-
-		if (imgPlay == null) {
-			loadImages();
-		}
-
-		final String IMG_PREFIX = "image.button.thumb.";
-
-		clickAreaPlay = new ColumnImageClickArea(COLUMN_ID, BTN_PLAY, IMG_PREFIX
-				+ BTN_PLAY);
-		clickAreaPlay.setTooltip(MessageText.getString("v3.MainWindow.button.play"));
-		listClickAreas.add(clickAreaPlay);
-
-		clickAreaDetails = new ColumnImageClickArea(COLUMN_ID, BTN_DETAILS,
-				IMG_PREFIX + BTN_DETAILS);
-		clickAreaDetails.setTooltip(MessageText.getString("v3.MainWindow.button.viewdetails"));
-		listClickAreas.add(clickAreaDetails);
-
-		clickAreaDL = new ColumnImageClickArea(COLUMN_ID, BTN_DL, IMG_PREFIX
-				+ BTN_DL);
-		clickAreaDL.setTooltip(MessageText.getString("v3.MainWindow.button.download"));
-		listClickAreas.add(clickAreaDL);
-
-		clickAreaRun = new ColumnImageClickArea(COLUMN_ID, BTN_RUN, IMG_PREFIX
-				+ BTN_RUN);
-		clickAreaRun.setTooltip(MessageText.getString("v3.MainWindow.button.run"));
-		listClickAreas.add(clickAreaRun);
-
-		clickAreaShare = new ColumnImageClickArea(COLUMN_ID, BTN_SHARE, IMG_PREFIX
-				+ BTN_SHARE);
-		clickAreaShare.setTooltip(MessageText.getString("v3.MainWindow.button.share"));
-		listClickAreas.add(clickAreaShare);
-	}
-
-	private void loadImages() {
-		ImageLoader imageLoader = ImageLoader.getInstance();
-		imgPlay = imageLoader.getImage("image.thumb.play");
-		if (imgPlay != null) {
-			imgPlayBounds = imgPlay.getBounds();
-		}
-	}
-
-	public void cellAdded(TableCell cell) {
-		cell.setMarginWidth(0);
-		cell.setMarginHeight(0);
-
-		for (Iterator iter = listClickAreas.iterator(); iter.hasNext();) {
-			ColumnImageClickArea clickArea = (ColumnImageClickArea) iter.next();
-			clickArea.addCell(cell);
-		}
-
-		TableRow tableRow = cell.getTableRow();
-		if (tableRow != null) {
-			tableRow.addMouseListener(this);
-		}
-	}
-
-	public void dispose(TableCell cell) {
-		mapCellTorrent.remove(cell);
-		disposeOldImage(cell);
-	}
-
-	public void refresh(TableCell cell) {
-		refresh(cell, false);
-	}
-
-	public void refresh(final TableCell cell, final boolean bForce) {
-		Object ds = cell.getDataSource();
-		DownloadManager dm = DataSourceUtils.getDM(ds);
-
-		//System.out.println("refresh " + bForce + " via " + Debug.getCompressedStackTrace(10));
-
-		TOTorrent newTorrent = DataSourceUtils.getTorrent(ds);
-		long lastUpdated = PlatformTorrentUtils.getContentLastUpdated(newTorrent);
-		// xxx hack.. cell starts with 0 sort value
-		if (lastUpdated == 0) {
-			lastUpdated = -1;
-		}
-
-		boolean bChanged = cell.setSortValue(lastUpdated) || bForce;
-
-		TOTorrent torrent = (TOTorrent) mapCellTorrent.get(cell);
-
-		if (newTorrent == torrent && !bChanged && cell.isValid()) {
-			return;
-		}
-
-		if (!Utils.isThisThreadSWT()) {
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					refresh(cell, bForce);
-				}
-			});
-			return;
-		}
-
-		if (!bForce && !cell.isShown()) {
-			return;
-		}
-
-		boolean cellHasMouse = (cell instanceof TableCellCore)
-				? ((TableCellCore) cell).isMouseOver() : false;
-				cellHasMouse = true;
-
-		torrent = newTorrent;
-		mapCellTorrent.put(cell, torrent);
-
-		// only dispose of old graphic if it's a thumbnail
-		disposeOldImage(cell);
-
-		byte[] b = null;
-		boolean canPlay = PlayUtils.canPlayDS(ds);
-		boolean showPlayButton = false; // TorrentListViewsUtils.canPlay(dm);
-		if (ds instanceof VuzeActivitiesEntry) {
-			b = ((VuzeActivitiesEntry) ds).getImageBytes();
-		}
-		if (b == null) {
-			b = PlatformTorrentUtils.getContentThumbnail(torrent);
-		}
-
-		boolean canRun = !canPlay && dm != null;
-		if (canRun && dm != null && !dm.getAssumedComplete()) {
-			canRun = false;
-		}
-
-		Image firstImage = null;
-		int dx = 0;
-		int dy = 0;
-		if (b == null) {
-			// Don't ever dispose of PathIcon, it's cached and may be used elsewhere
-			String path = null;
-			if (dm == null) {
-				TOTorrentFile[] files = torrent.getFiles();
-				if (files.length > 0) {
-					path = files[0].getRelativePath();
-				}
-			} else {
-				path = dm.getDownloadState().getPrimaryFile();
-			}
-			if (path != null) {
-				firstImage = ImageRepository.getPathIcon(path, true, torrent != null
-						&& !torrent.isSimpleTorrent());
-			}
-		}
-
-		int cellWidth = cell.getWidth();
-		int cellHeight = cell.getHeight();
-
-		int MAXH = maxThumbHeight < 0 ? cell.getHeight() : maxThumbHeight;
-		if (ICONS_BELOW) {
-			MAXH -= (IMG_SIZE + 5);
-		}
-
-		TableRow row = cell.getTableRow();
-		if (ROW_HOVER) {
-			boolean rowHasMouse = (row instanceof TableRowCore)
-					? ((TableRowCore) row).isMouseOver() : false;
-			showPlayButton &= rowHasMouse;
-		} else {
-			showPlayButton &= cellHasMouse;
-		}
-
-		boolean disposeImage = false;
-		if (firstImage == null) {
-			if (b != null) {
-				ByteArrayInputStream bis = new ByteArrayInputStream(b);
-				firstImage = new Image(Display.getDefault(), bis);
-			} else {
-				firstImage = new Image(Display.getDefault(), 1, 1);
-			}
-			disposeImage = true;
-		}
-		Image newImg = null;
-		try {
-			int w = firstImage.getBounds().width;
-			int h = firstImage.getBounds().height;
-
-			int h2;
-			int w2;
-			int hImg;
-			int wImg;
-			boolean smaller = false;
-
-			if (h > MAXH) {
-				hImg = h2 = MAXH;
-				wImg = w2 = h2 * w / h;
-			} else {
-				h2 = MAXH;
-				hImg = h;
-				w2 = h2 * w / h;
-				wImg = hImg * w / h;
-				dy = (h2 - hImg) / 2;
-				smaller = true;
-			}
-
-			if (cellWidth > wImg) {
-				dx = (cellWidth - wImg) / 2;
-			}
-			//dx += 18;
-
-			newImg = new Image(firstImage.getDevice(), cellWidth, cellHeight);
-
-			GC gc = new GC(newImg);
-			gc.setAdvanced(true);
-			try {
-				gc.setInterpolation(SWT.HIGH);
-				gc.setAntialias(SWT.ON);
-			} catch (Exception e) {
-				// may not be avail
-			}
-			//gc.setBackground(ColorCache.getColor(firstImage.getDevice(), 40, 40, 40));
-			int[] bg = cell.getBackground();
-			if (bg != null) {
-				gc.setBackground(ColorCache.getColor(firstImage.getDevice(), bg));
-				gc.fillRectangle(newImg.getBounds());
-			}
-
-			gc.setBackground(ColorCache.getColor(firstImage.getDevice(),
-	  			"COLOR_LIST_BACKGROUND"));
-			gc.setForeground(ColorCache.getColor(firstImage.getDevice(),
-			"COLOR_WIDGET_LIGHT_SHADOW"));
-			if (smaller) {
-  			gc.fillRoundRectangle(0, 0, cellWidth - 1, h2, 11, 8);
-  			gc.drawRoundRectangle(0, 0, cellWidth - 1, h2, 11, 8);
-  			//gc.drawRectangle(0, 0, cellWidth - 1, h2);
-			}
-			gc.fillRoundRectangle(0, h2 + 2, cellWidth - 1, cellHeight - h2 - 3, 11, 8);
-			//gc.drawRoundRectangle(0, h2 + 2, cellWidth - 1, cellHeight - h2 - 3, 11, 8);
-  			//gc.fillRectangle(2, 2, (int) (h2 * 1.77f) - 4, h2 - 4);
-  			//gc.fillRectangle(newImg.getBounds());
-
-			if (cellHasMouse && SET_ALPHA) {
-				bg = cell.getBackground();
-				if (bg != null) {
-					gc.setBackground(ColorCache.getColor(firstImage.getDevice(), bg));
-					gc.fillRectangle(newImg.getBounds());
-				}
-				try {
-					gc.setAlpha(40);
-				} catch (Exception e) {
-					// Ignore ERROR_NO_GRAPHICS_LIBRARY error or any others
-				}
-			}
-			gc.drawImage(firstImage, 0, 0, w, h, dx + BORDER_SIZE, dy + BORDER_SIZE,
-					wImg - (BORDER_SIZE * 2), hImg - (BORDER_SIZE * 2));
-
-			if (cell instanceof TableCellSWT) {
-				TableCellSWT cellSWT = (TableCellSWT) cell;
-				cellSWT.setCursorID(showPlayButton && cellSWT.isMouseOver()
-						? SWT.CURSOR_HAND : SWT.CURSOR_ARROW);
-			}
-
-			if (SET_ALPHA) {
-				try {
-					gc.setAlpha(255);
-				} catch (Exception e) {
-					// Ignore ERROR_NO_GRAPHICS_LIBRARY error or any others
-				}
-			}
-
-			float scale = (ds instanceof DownloadManager) ? 0.8f : 1.0f;
-			int imgSize = (int) (IMG_SIZE * scale);
-			int imgSizeHalf = (int) (IMG_SIZE_HALF * scale);
-			int border = (int) (4 * scale);
-			
-			boolean canShare = VuzeShareUtils.getInstance().canShare(ds);
-			
-			int yPos = ICONS_BELOW ? cellHeight - imgSize - 2 :  cellHeight / 2 - imgSizeHalf;
-
-			if (clickAreaDL != null) {
-				clickAreaDL.setPosition(cellWidth - imgSize - border, yPos);
-				clickAreaDL.setVisible(dm == null);
-				if (dm == null) {
-					canShare = false;
-				}
-			}
-			if (clickAreaDetails != null) {
-				clickAreaDetails.setPosition(border, yPos);
-				clickAreaDetails.setVisible(getHash(ds, true) != null);
-			}
-			if (clickAreaRun != null) {
-				clickAreaRun.setPosition(border, yPos);
-				clickAreaRun.setVisible(canRun);
-			}
-			if (clickAreaPlay != null) {
-				clickAreaPlay.setPosition(cellWidth / 2 - imgSizeHalf, yPos);
-				clickAreaPlay.setVisible(canPlay);
-			}
-			
-			if (clickAreaShare != null) {
-				clickAreaShare.setPosition(cellWidth - imgSize - border, yPos);
-				clickAreaShare.setVisible(canShare);
-			}
-
-			if (showPlayButton && imgPlay != null) {
-				int imgW = imgPlayBounds.width;
-				int imgH = imgPlayBounds.height;
-
-				float h3 = (int) (h2 * 0.8);
-				float w3 = h3 * imgW / imgH;
-				float x = (w2 - w3) / 2;
-				float y = (h2 - h3) / 2;
-
-				gc.drawImage(imgPlay, 0, 0, imgW, imgH, (int) x, (int) y, (int) (w3),
-						(int) (h3));
-			}
-
-			for (Iterator iter = listClickAreas.iterator(); iter.hasNext();) {
-				ColumnImageClickArea clickArea = (ColumnImageClickArea) iter.next();
-
-				if (cellHasMouse) {
-					clickArea.setScale(scale);
-					clickArea.drawImage(cell, gc);
-				}
-			}
-
-			gc.dispose();
-
-			if (disposeImage) {
-				firstImage.dispose();
-			}
-
-			if (newImg == null) {
-				cell.setGraphic(null);
-			} else {
-				Graphic graphic = new disposableUISWTGraphic(newImg);
-				cell.setGraphic(graphic);
-			}
-		} catch (Exception e) {
-			// ignore, probably invalid image
-		}
-	}
-
-	private String getHash(Object ds, boolean onlyOurs) {
-		if (onlyOurs && !DataSourceUtils.isPlatformContent(ds)) {
-			return null;
-		}
-		return DataSourceUtils.getHash(ds);
-	}
-
-	/**
-	 * 
-	 */
-	private void disposeOldImage(TableCell cell) {
-		Graphic oldGraphic = cell.getGraphic();
-		if (oldGraphic instanceof disposableUISWTGraphic) {
-			Image oldImage = ((UISWTGraphic) oldGraphic).getImage();
-			Utils.disposeSWTObjects(new Object[] {
-				oldImage
-			});
-		}
-	}
-
-	public void cellVisibilityChanged(TableCell cell, int visibility) {
-		if (visibility == TableCellVisibilityListener.VISIBILITY_HIDDEN) {
-			//log(cell, "whoo, save");
-			disposeOldImage(cell);
-		} else if (visibility == TableCellVisibilityListener.VISIBILITY_SHOWN) {
-			//log(cell, "whoo, draw");
-			refresh(cell, true);
-		}
-	}
-
-	private void log(TableCell cell, String s) {
-		System.out.println(((TableRowCore) cell.getTableRow()).getIndex() + ":"
-				+ System.currentTimeMillis() + ": " + s);
-	}
-
-	public class disposableUISWTGraphic
-		extends UISWTGraphicImpl
-	{
-		public disposableUISWTGraphic(Image newImage) {
-			super(newImage);
-		}
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellMouseListener#cellMouseTrigger(org.gudy.azureus2.plugins.ui.tables.TableCellMouseEvent)
-	public void cellMouseTrigger(TableCellMouseEvent event) {
-		if (event.data instanceof ColumnImageClickArea) {
-			if (!((TableCellCore) event.cell).isMouseOver()) {
-				return;
-			}
-
-			ColumnImageClickArea clickArea = (ColumnImageClickArea) event.data;
-			String id = clickArea.getId();
-
-			if (id.equals(BTN_PLAY)) {
-				String referal = null;
-				Object ds = event.cell.getDataSource();
-				if (ds instanceof VuzeActivitiesEntry) {
-					if (((VuzeActivitiesEntry) ds).isDRM()
-							&& ((VuzeActivitiesEntry) ds).getDownloadManger() == null) {
-						if (DataSourceUtils.isPlatformContent(ds)) {
-							TorrentListViewsUtils.viewDetailsFromDS(ds, "thumb");
-						}
-						return;
-					}
-					referal = DLReferals.DL_REFERAL_PLAYDASHACTIVITY + "-"
-							+ ((VuzeActivitiesEntry) ds).getTypeID();
-				}
-				TorrentListViewsUtils.playOrStreamDataSource(ds, null, referal);
-			} else if (id.equals(BTN_DL)) {
-				String referal = null;
-				Object ds = event.cell.getDataSource();
-				if (ds instanceof VuzeActivitiesEntry) {
-					if (((VuzeActivitiesEntry) ds).isDRM()) {
-						if (DataSourceUtils.isPlatformContent(ds)) {
-							TorrentListViewsUtils.viewDetailsFromDS(ds, "thumb");
-						}
-						return;
-					}
-
-					referal = DLReferals.DL_REFERAL_DASHACTIVITY + "-"
-							+ ((VuzeActivitiesEntry) ds).getTypeID();
-				}
-				TorrentListViewsUtils.downloadDataSource(ds, false, referal);
-			} else if (id.equals(BTN_DETAILS)) {
-				Object ds = event.cell.getDataSource();
-				if (DataSourceUtils.isPlatformContent(ds)) {
-					TorrentListViewsUtils.viewDetailsFromDS(ds, "thumb");
-				}
-			} else if (id.equals(BTN_RUN)) {
-				// run via play or stream so we get the security warning
-				Object ds = event.cell.getDataSource();
-				TorrentListViewsUtils.playOrStreamDataSource(ds, null,
-						DLReferals.DL_REFERAL_UNKNOWN);
-			} else if (id.equals(BTN_SHARE)) {
-				ISelectedContent[] contents = SelectedContentManager.getCurrentlySelectedContent();
-				if (contents.length > 0) {
-					String referer = event.cell.getTableID() + "-media-thumb-btn";
-					VuzeShareUtils.getInstance().shareContent(contents[0], null, referer);
-				}
-			}
-
-			return;
-		}
-
-		boolean changed = false;
-		if (event.eventType == TableRowMouseEvent.EVENT_MOUSEENTER) {
-			changed = true;
-		} else if (event.eventType == TableRowMouseEvent.EVENT_MOUSEEXIT) {
-			changed = true;
-		}
-		if (changed && event.cell != null) {
-			invalidateAndRefresh(event.cell);
-		}
-	}
-
-	/**
-	 * @param cell
-	 *
-	 * @since 3.0.5.3
-	 */
-	private void invalidateAndRefresh(TableCell cell) {
-		cell.invalidate();
-		if (cell instanceof TableCellCore) {
-			TableCellCore cellCore = (TableCellCore) cell;
-			cellCore.refreshAsync();
-		}
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableRowMouseListener#rowMouseTrigger(org.gudy.azureus2.plugins.ui.tables.TableRowMouseEvent)
-	public void rowMouseTrigger(TableRowMouseEvent event) {
-		//if (event instanceof TableCellMouseEvent) {
-		//	rowMouseTrigger(event, ((TableCellMouseEvent)event).cell);
-		//}
-		rowMouseTrigger(event, event.row.getTableCell(COLUMN_ID));
-	}
-
-	public void rowMouseTrigger(TableRowMouseEvent event, TableCell cell) {
-		boolean changed = false;
-		if (event.eventType == TableRowMouseEvent.EVENT_MOUSEENTER) {
-			changed = true;
-		} else if (event.eventType == TableRowMouseEvent.EVENT_MOUSEEXIT) {
-			changed = true;
-		}
-		if (changed && cell != null) {
-			cell.invalidate();
-			invalidateAndRefresh(cell);
-		}
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellToolTipListener#cellHover(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void cellHover(TableCell cell) {
-		if (cell.getToolTip() != null) {
-			return;
-		}
-
-		Object ds = cell.getDataSource();
-		DownloadManager dm = DataSourceUtils.getDM(ds);
-		if (dm != null) {
-			cell.setToolTip(PlatformTorrentUtils.getContentTitle2(dm));
-		}
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellToolTipListener#cellHoverComplete(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void cellHoverComplete(TableCell cell) {
-		cell.setToolTip(null);
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnProgressETA.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnProgressETA.java
index 6fe0f3a..ae0d20f 100644
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnProgressETA.java
+++ b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnProgressETA.java
@@ -17,6 +17,7 @@ import org.gudy.azureus2.core3.util.UrlUtils;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
 import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
 import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
@@ -51,7 +52,7 @@ public class ColumnProgressETA
 	public static final long SHOW_ETA_AFTER_MS = 30000;
 
 	private final static Object CLICK_KEY = new Object();
-	
+
 	private static Font fontText = null;
 
 	Display display;
@@ -63,7 +64,7 @@ public class ColumnProgressETA
 	private Color cBorder;
 
 	private Color cText;
-		
+
 	Color textColor;
 
 	/**
@@ -76,7 +77,7 @@ public class ColumnProgressETA
 		setMinWidth(COLUMN_WIDTH);
 
 		display = SWTThread.getInstance().getDisplay();
-		
+
 		SWTSkinProperties skinProperties = SWTSkinFactory.getInstance().getSkinProperties();
 		cBG = skinProperties.getColor("color.progress.bg");
 		if (cBG == null) {
@@ -107,39 +108,39 @@ public class ColumnProgressETA
 	public void cellAdded(TableCell cell) {
 		new Cell(cell);
 	}
-	
-	public void 
-	cellMouseTrigger(
-		TableCellMouseEvent event ) 
-	{
+
+	public void cellMouseTrigger(TableCellMouseEvent event) {
 
 		DownloadManager dm = (DownloadManager) event.cell.getDataSource();
-		if (dm == null) {return;}
-		
-		String clickable = (String)dm.getUserData( CLICK_KEY );
-		
-		if ( clickable == null ){
-			
+		if (dm == null) {
+			return;
+		}
+
+		String clickable = (String) dm.getUserData(CLICK_KEY);
+
+		if (clickable == null) {
+
 			return;
 		}
-		
+
 		event.skipCoreFunctionality = true;
-		
-		if ( event.eventType == TableCellMouseEvent.EVENT_MOUSEUP ){
-		
-			String url = UrlUtils.getURL( clickable );
-			
-			if ( url != null ){
-				
-				Utils.launch( url );
+
+		if (event.eventType == TableCellMouseEvent.EVENT_MOUSEUP) {
+
+			String url = UrlUtils.getURL(clickable);
+
+			if (url != null) {
+
+				Utils.launch(url);
 			}
 		}
 	}
-	
+
 	private class Cell
-		implements TableCellRefreshListener,
-		TableCellSWTPaintListener
+		implements TableCellRefreshListener, TableCellSWTPaintListener
 	{
+		private static final int MAX_PROGRESS_FILL_HEIGHT = 19;
+
 		int lastPercentDone = 0;
 
 		long lastETA;
@@ -147,7 +148,6 @@ public class ColumnProgressETA
 		public Cell(TableCell cell) {
 			cell.addListeners(this);
 			cell.setMarginHeight(3);
-			//cell.setFillCell(true);
 		}
 
 		public void refresh(TableCell cell) {
@@ -162,16 +162,14 @@ public class ColumnProgressETA
 
 			long completedTime = dm.getDownloadState().getLongParameter(
 					DownloadManagerState.PARAM_DOWNLOAD_COMPLETED_TIME);
-			if (completedTime <= 0) {
-				sortValue = dm.getDownloadState().getLongParameter(
-						DownloadManagerState.PARAM_DOWNLOAD_ADDED_TIME) * 10000;
-				sortValue += 1000 - percentDone;
+			if (completedTime <= 0 || !dm.isDownloadComplete(false)) {
+				sortValue = Long.MAX_VALUE - 10000 + percentDone;
 			} else {
 				sortValue = completedTime;
 			}
 
 			long eta = getETA(cell);
-			
+
 			if (!cell.setSortValue(sortValue) && cell.isValid()
 					&& lastPercentDone == percentDone && lastETA == eta) {
 				return;
@@ -180,84 +178,65 @@ public class ColumnProgressETA
 			lastPercentDone = percentDone;
 			lastETA = eta;
 
-			cell.setSortValue(sortValue);
 			cell.invalidate();
 		}
-		
+
 		// @see org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener#cellPaint(org.eclipse.swt.graphics.GC, org.gudy.azureus2.ui.swt.views.table.TableCellSWT)
-		public void cellPaint(GC gcImage, TableCellSWT cell) {
+		public void cellPaint(GC gc, TableCellSWT cell) {
 			DownloadManager dm = (DownloadManager) cell.getDataSource();
 			if (dm == null) {
 				return;
 			}
 			int percentDone = getPercentDone(cell);
 			long eta = getETA(cell);
-		
+
 			//Compute bounds ...
 			int newWidth = cell.getWidth();
 			if (newWidth <= 0) {
 				return;
 			}
 			int newHeight = cell.getHeight();
-			
-			Color fgFirst = gcImage.getForeground();
-			
+
+			Color fgFirst = gc.getForeground();
+
 			Rectangle cellBounds = cell.getBounds();
-			
-			int x0 = cellBounds.x + cell.getMarginWidth();
-			int y0 = cellBounds.y + cell.getMarginHeight();
-
-			int x1 = borderWidth;
-			int y1 = borderWidth;
-			int x2 = newWidth - x1 - borderWidth;
-			int progressX2 = x2;
-			int progressY2 = newHeight - y1 - borderWidth - 13;
-			if (progressY2 > 18) {
-				progressY2 = 18;
-			}
-			boolean showSecondLine = progressY2 > 0;
-			if (!showSecondLine) {
-				progressY2 = newHeight;
-			}
-			
-			if (x2 < 10 || progressX2 < 10) {
+
+			int xStart = cellBounds.x + cell.getMarginWidth();
+			int yStart = cellBounds.y + cell.getMarginHeight();
+
+			int xRelProgressFillStart = borderWidth;
+			int yRelProgressFillStart = borderWidth;
+			int xRelProgressFillEnd = newWidth - xRelProgressFillStart - borderWidth;
+			int yRelProgressFillEnd = yRelProgressFillStart + 13;
+			boolean showSecondLine = yRelProgressFillEnd + 10 < newHeight;
+
+			if (xRelProgressFillEnd < 10 || xRelProgressFillEnd < 10) {
 				return;
 			}
 
 			boolean bDrawProgressBar = true;
 
 			String sETALine = null;
-			long lSpeed = getSpeed(dm);
-			String sSpeed = lSpeed <= 0 ? "" : "("
-					+ DisplayFormatters.formatByteCountToKiBEtcPerSec(lSpeed, true) + ")";
 
+			// Draw Progress bar
 			if (bDrawProgressBar && percentDone < 1000) {
-
-		    ImageLoader imageLoader = ImageLoader.getInstance();
+				ImageLoader imageLoader = ImageLoader.getInstance();
 				Image imgEnd = imageLoader.getImage("dl_bar_end");
 				Image img0 = imageLoader.getImage("dl_bar_0");
 				Image img1 = imageLoader.getImage("dl_bar_1");
 
-				gcImage.drawImage(imgEnd, x0, y0+y1);
-				gcImage.drawImage(imgEnd, x0 + progressX2 - x1 + 1, y0+y1);
-				
-				
-				
-//				gcImage.setForeground(cBorder);
-//				gcImage.drawRectangle(x0, y0, progressX2 - x1 + 1, progressY2 - y1 + 1);
-
-				int limit = ((progressX2 - x1) * percentDone) / 1000;
-
-				gcImage.drawImage(img1, 0, 0, 1, 13,x0 + x1, y0 + y1, limit, 13);
-				
-				
-//				gcImage.setBackground(cBG);
-//				gcImage.fillRectangle(x0 + x1, y0 + y1, limit, progressY2 - y1);
-				if (limit < progressX2) {
-					gcImage.drawImage(img0, 0, 0, 1, 13, x0 + limit + 1, y0 + y1, progressX2 - limit - 1,13);
-//					gcImage.setBackground(cFG);
-//					gcImage.fillRectangle(x0 + limit + 1, y0 + y1, progressX2 - limit - 1,
-//							progressY2 - y1);
+				gc.drawImage(imgEnd, xStart, yStart + yRelProgressFillStart);
+				gc.drawImage(imgEnd, xStart + xRelProgressFillEnd
+						- xRelProgressFillStart + 1, yStart + yRelProgressFillStart);
+
+				int limit = ((xRelProgressFillEnd - xRelProgressFillStart) * percentDone) / 1000;
+
+				gc.drawImage(img1, 0, 0, 1, 13, xStart + xRelProgressFillStart, yStart
+						+ yRelProgressFillStart, limit, 13);
+
+				if (limit < xRelProgressFillEnd) {
+					gc.drawImage(img0, 0, 0, 1, 13, xStart + limit + 1, yStart
+							+ yRelProgressFillStart, xRelProgressFillEnd - limit - 1, 13);
 				}
 
 				imageLoader.releaseImage("dl_bar_end");
@@ -266,15 +245,12 @@ public class ColumnProgressETA
 			}
 
 			if (sETALine == null) {
-				if ( dm.isUnauthorisedOnTracker()){
+				if (dm.isUnauthorisedOnTracker()) {
 					sETALine = dm.getTrackerStatus();
 					// fgFirst = Colors.colorError;	pftt, no colours allowed apparently
-				}else{
-					//if (isStopped(cell)) {
-					//sETALine = DisplayFormatters.formatDownloadStatus((DownloadManager) cell.getDataSource());
-					//} else
+				} else {
 					if (dm.isDownloadComplete(true)) {
-						sETALine = DisplayFormatters.formatByteCountToKiBEtc(dm.getSize());
+						//sETALine = DisplayFormatters.formatByteCountToKiBEtc(dm.getSize());
 					} else if (eta > 0) {
 						String sETA = TimeFormatter.format(eta);
 						sETALine = MessageText.getString(
@@ -283,59 +259,76 @@ public class ColumnProgressETA
 								});
 					} else {
 						sETALine = DisplayFormatters.formatDownloadStatus(dm);
-						//sETALine = "";
 					}
 				}
-				
+
 				int cursor_id;
-				
-				if ( sETALine.indexOf( "http://" ) == -1 ){
-									
-					dm.setUserData( CLICK_KEY, null );
-					
+
+				if (sETALine != null && sETALine.indexOf("http://") == -1) {
+
+					dm.setUserData(CLICK_KEY, null);
+
 					cursor_id = SWT.CURSOR_ARROW;
-					
-				}else{
-					
-					dm.setUserData( CLICK_KEY, sETALine );
-					
+
+				} else {
+
+					dm.setUserData(CLICK_KEY, sETALine);
+
 					cursor_id = SWT.CURSOR_HAND;
-					
-					if ( !cell.getTableRow().isSelected()){
-					
+
+					if (!cell.getTableRow().isSelected()) {
+
 						fgFirst = Colors.blue;
 					}
 				}
-				
-				((TableCellSWT)cell).setCursorID( cursor_id );
+
+				((TableCellSWT) cell).setCursorID(cursor_id);
 			}
 
 			if (fontText == null) {
-				fontText = Utils.getFontWithHeight(gcImage.getFont(), gcImage, 11);
+				fontText = Utils.getFontWithHeight(gc.getFont(), gc, 11);
 			}
 
-			gcImage.setTextAntialias(SWT.ON);
-			if (showSecondLine) {
-  			gcImage.setFont(fontText);
-  			//int[] fg = cell.getForeground();
-  			//gcImage.setForeground(ColorCache.getColor(display, fg[0], fg[1], fg[2]));
-  			gcImage.setForeground(fgFirst);
-  			gcImage.drawText(sETALine, x0 + 2, y0 + progressY2, true);
-  			Point textExtent = gcImage.textExtent(sETALine);
-  			cell.setToolTip(textExtent.x > newWidth ? sETALine : null);
+			gc.setTextAntialias(SWT.ON);
+			gc.setFont(fontText);
+			if (showSecondLine && sETALine != null) {
+				gc.setForeground(fgFirst);
+				boolean over = GCStringPrinter.printString(gc, sETALine, new Rectangle(
+						xStart + 2, yStart + yRelProgressFillEnd, xRelProgressFillEnd,
+						newHeight - yRelProgressFillEnd), true, false, SWT.CENTER);
+				cell.setToolTip(over ? sETALine : null);
 			}
-			int middleY = (progressY2 - 12) / 2;
+			int middleY = (yRelProgressFillEnd - 12) / 2;
 			if (percentDone == 1000) {
-				gcImage.setForeground(cText);
-				gcImage.drawText("Complete", x0 + 2, y0 + middleY, true);
+				gc.setForeground(fgFirst);
+				long value;
+				long completedTime = dm.getDownloadState().getLongParameter(
+						DownloadManagerState.PARAM_DOWNLOAD_COMPLETED_TIME);
+				if (completedTime <= 0) {
+					value = dm.getDownloadState().getLongParameter(
+							DownloadManagerState.PARAM_DOWNLOAD_ADDED_TIME);
+				} else {
+					value = completedTime;
+				}
+
+				String s = "Completed on " + DisplayFormatters.formatDateShort(value);
+				GCStringPrinter.printString(gc, s, new Rectangle(xStart + 2, yStart,
+						newWidth - 4, newHeight), true, false, SWT.WRAP);
 			} else if (bDrawProgressBar) {
-				gcImage.setForeground(cText);
+				long lSpeed = getSpeed(dm);
+				String sSpeed = lSpeed <= 0 ? "" : "("
+						+ DisplayFormatters.formatByteCountToKiBEtcPerSec(lSpeed, true)
+						+ ")";
+
+				gc.setForeground(cText);
 				String sPercent = DisplayFormatters.formatPercentFromThousands(percentDone);
-				gcImage.drawText(sSpeed, x0 + 50, y0 + y1 + 1, true);
-				gcImage.drawText(sPercent, x0 + 2, y0 + y1 + 1, true);
+				gc.drawText(sSpeed, xStart + 50, yStart + yRelProgressFillStart + 1,
+						true);
+				gc.drawText(sPercent, xStart + 2, yStart + yRelProgressFillStart + 1,
+						true);
 			}
-  
-			gcImage.setFont(null);
+
+			gc.setFont(null);
 		}
 
 		private int getPercentDone(TableCell cell) {
@@ -390,7 +383,6 @@ public class ColumnProgressETA
 			return dmEnhancer.getEnhancedDownload(dm);
 		}
 
-
 		private void log(TableCell cell, String s) {
 			System.out.println(((TableRowCore) cell.getTableRow()).getIndex() + ":"
 					+ System.currentTimeMillis() + ": " + s);
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnQuality.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnQuality.java
deleted file mode 100644
index 81ffdab..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnQuality.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * 
- */
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.*;
-
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.util.DataSourceUtils;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Jun 13, 2006
- *
- */
-public class ColumnQuality
-	extends CoreTableColumn
-	implements TableCellAddedListener, TableCellRefreshListener,
-	TableCellSWTPaintListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-	public static final String COLUMN_ID = "Quality";
-
-	public void fillTableColumnInfo(TableColumnInfo info) {
-		info.addCategories(new String[] { CAT_CONTENT });
-	}
-
-	public Font font;
-
-	private final static int COLUMN_WIDTH = 50;
-
-	/**
-	 * 
-	 */
-	public ColumnQuality(String sTableID) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_CENTER, COLUMN_WIDTH, sTableID);
-		initializeAsGraphic(COLUMN_WIDTH);
-	}
-
-	public void cellAdded(TableCell cell) {
-		cell.setMarginWidth(0);
-		cell.setMarginHeight(0);
-	}
-
-	// @see org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener#cellPaint(org.eclipse.swt.graphics.GC, org.gudy.azureus2.ui.swt.views.table.TableCellSWT)
-	public void cellPaint(GC gc, TableCellSWT cell) {
-		Rectangle cellBounds = cell.getBounds();
-		TOTorrent torrent = DataSourceUtils.getTorrent(cell.getDataSource());
-
-		String quality = PlatformTorrentUtils.getContentQuality(torrent);
-		String imageID = "icon.quality." + quality;
-		Image img = ImageLoader.getInstance().getImage(imageID);
-		try {
-  		if (ImageLoader.isRealImage(img)) {
-  			Rectangle imgBounds = img.getBounds();
-  
-  			if (imgBounds.height <= cellBounds.height) {
-  				gc.drawImage(img, cellBounds.x
-  						+ ((cellBounds.width - imgBounds.width) / 2), cellBounds.y
-  						+ ((cellBounds.height - imgBounds.height) / 2));
-  				return;
-  			}
-  		}
-  		GCStringPrinter.printString(gc, quality, cellBounds, true, false,
-  				SWT.CENTER);
-		} finally {
-			ImageLoader.getInstance().releaseImage(imageID);
-		}
-	}
-
-	public void refresh(TableCell cell) {
-		TOTorrent torrent = DataSourceUtils.getTorrent(cell.getDataSource());
-		String quality = PlatformTorrentUtils.getContentQuality(torrent);
-		cell.setSortValue(quality);
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnRate.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnRate.java
deleted file mode 100644
index 9ef7b77..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnRate.java
+++ /dev/null
@@ -1,783 +0,0 @@
-/*
- * Created on Jun 16, 2006 2:41:08 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import java.util.Map;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.Display;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.mainwindow.HSLColor;
-import org.gudy.azureus2.ui.swt.plugins.UISWTGraphic;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
-import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.core.messenger.PlatformMessage;
-import com.aelitis.azureus.core.messenger.PlatformMessengerListener;
-import com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger;
-import com.aelitis.azureus.core.messenger.config.RatingUpdateListener2;
-import com.aelitis.azureus.core.torrent.GlobalRatingUtils;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.core.torrent.RatingInfoList;
-import com.aelitis.azureus.ui.common.table.TableCellCore;
-import com.aelitis.azureus.ui.common.table.TableRowCore;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinFactory;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinProperties;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.Graphic;
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Jun 16, 2006
- */
-public class ColumnRate
-	extends CoreTableColumn
-	implements TableCellAddedListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-	public static final String COLUMN_ID = "Rating";
-
-	public static final int COLUMN_WIDTH = 58;
-
-	public static final boolean ROW_HOVER = System.getProperty("rowhover", "0").equals(
-			"1");
-
-	private static Font font = null;
-
-	private static Font smallFont = null;
-
-	private static Image imgRateMe;
-
-	private static Image imgRateMeUp;
-
-	private static Image imgRateMeDown;
-
-	private static Image imgUpSmall;
-
-	private static Image imgDownSmall;
-
-	private static Image imgUp;
-
-	private static Image imgDown;
-
-	private static Image imgWait;
-
-	private static Image imgRateMeButton;
-
-	private static Image imgRateMeButtonEnabled;
-
-	private static Image imgRateMeButtonDisabled;
-
-	private static Rectangle boundsRateMe;
-
-	private static int width;
-
-	private boolean useButton;
-
-	private boolean disabled;
-
-	private boolean allowRate = true;
-
-	static {
-		imgRateMe = ImageLoader.getInstance().getImage("icon.rateme");
-		boundsRateMe = imgRateMe.getBounds();
-		width = boundsRateMe.width;
-
-		imgRateMeButtonEnabled = ImageLoader.getInstance().getImage(
-				"icon.rateme-button");
-		imgRateMeButton = imgRateMeButtonEnabled;
-		width = Math.max(width, imgRateMeButton.getBounds().width);
-
-		imgRateMeButtonDisabled = ImageLoader.getInstance().getImage(
-				"icon.rateme-button-disabled");
-		width = Math.max(width, imgRateMeButtonDisabled.getBounds().width);
-
-		imgRateMeUp = ImageLoader.getInstance().getImage("icon.rateme.up");
-		imgRateMeDown = ImageLoader.getInstance().getImage(
-				"icon.rateme.down");
-
-		imgWait = ImageLoader.getInstance().getImage("icon.rate.wait");
-		width = Math.max(width, imgWait.getBounds().width);
-
-		imgDown = ImageLoader.getInstance().getImage("icon.rate.down");
-		imgUp = ImageLoader.getInstance().getImage("icon.rate.up");
-
-		imgDownSmall = ImageLoader.getInstance().getImage(
-				"icon.rate.small.down");
-		imgUpSmall = ImageLoader.getInstance().getImage("icon.rate.small.up");
-	}
-
-	public ColumnRate(String sTableID) {
-		this(sTableID, false);
-	}
-
-	/**
-	 * 
-	 */
-	public ColumnRate(String sTableID, boolean allowRate) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_LEAD, COLUMN_WIDTH, sTableID);
-		this.allowRate = allowRate;
-		initializeAsGraphic(COLUMN_WIDTH);
-		setAlignment(ALIGN_TRAIL);
-		setWidthLimits(COLUMN_WIDTH, COLUMN_WIDTH);
-	}
-
-	public void fillTableColumnInfo(TableColumnInfo info) {
-		info.addCategories(new String[] {
-			CAT_CONTENT
-		});
-	}
-
-	public void cellAdded(TableCell cell) {
-		PlatformRatingMessenger.setGlobalRatingUpdateDelayed(false);
-		new Cell(cell);
-	}
-
-	private class Cell
-		implements TableCellRefreshListener, TableCellDisposeListener,
-		TableCellMouseMoveListener, TableCellToolTipListener,
-		TableRowMouseListener, RatingUpdateListener2, TableCellVisibilityListener
-	{
-		String rating = "--";
-
-		private boolean bMouseDowned;
-
-		private int hoveringOn = -1;
-
-		private DownloadManager dm;
-
-		private TableCell cell;
-
-		private Rectangle areaUserRating = null;
-
-		public Cell(final TableCell cell) {
-			this.cell = cell;
-			PlatformRatingMessenger.addListener(this);
-			cell.addListeners(this);
-			cell.setMarginWidth(0);
-			cell.setMarginHeight(0);
-
-			dm = getDM(cell.getDataSource());
-			if (dm != null) {
-				boolean isContent = PlatformTorrentUtils.isContent(dm.getTorrent(),
-						true);
-				if (!isContent) {
-					rating = "";
-					return;
-				}
-			}
-			TableRow tableRow = cell.getTableRow();
-			if (tableRow != null) {
-				tableRow.addMouseListener(this);
-			}
-		}
-
-		public void dispose(TableCell cell) {
-			PlatformRatingMessenger.removeListener(this);
-			disposeOldImage(cell);
-		}
-
-		// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
-		public void refresh(TableCell cell) {
-			refresh(cell, false);
-		}
-
-		public void refresh(final TableCell cell, final boolean force) {
-			if (cell.isDisposed()) {
-				return;
-			}
-			DownloadManager newDM = getDM(cell.getDataSource());
-			if (dm == null || newDM != dm) {
-				if (newDM == null) {
-					return;
-				}
-				dm = newDM;
-			}
-
-			if (!Utils.isThisThreadSWT()) {
-				Utils.execSWTThread(new AERunnable() {
-					public void runSupport() {
-						refresh(cell, force);
-					}
-				});
-				return;
-			}
-			DownloadManager dm = getDM(cell.getDataSource());
-			if (dm == null) {
-				return;
-			}
-
-			TOTorrent torrent = dm.getTorrent();
-			String rating = GlobalRatingUtils.getRatingString(torrent);
-			long count = GlobalRatingUtils.getCount(torrent);
-			int userRating = -3;
-			if (PlatformTorrentUtils.isContent(dm.getTorrent(), true)) {
-				userRating = PlatformTorrentUtils.getUserRating(dm.getTorrent());
-			}
-
-			boolean b;
-			try {
-				float val = Float.parseFloat(rating) * 1000000 + count;
-				val += (userRating + 3) * 10000000;
-				b = !cell.setSortValue(val);
-			} catch (Exception e) {
-				b = !cell.setSortValue(count > 0 ? new Float(count) : null);
-			}
-
-			if (!force) {
-				if (b && cell.isValid()) {
-					return;
-				}
-				if (!cell.isShown()) {
-					return;
-				}
-			}
-
-			int width = cell.getWidth();
-			int height = cell.getHeight();
-			if (width <= 0 || height <= 0) {
-				return;
-			}
-			boolean needsFill = false;
-			Image img = ((UISWTGraphic) cell.getBackgroundGraphic()).getImage();
-			if (img == null) {
-				img = new Image(Display.getDefault(), width, height);
-				needsFill = true;
-			}
-
-			// draw border
-			GC gcImage = new GC(img);
-
-			if (needsFill) {
-				int[] bg = cell.getBackground();
-				if (bg != null) {
-					gcImage.setBackground(ColorCache.getColor(gcImage.getDevice(), bg[0],
-							bg[1], bg[2]));
-					gcImage.fillRectangle(0, 0, width, height);
-				}
-			}
-
-			boolean showAverage = !useButton;
-			boolean showRateActionIcon = useButton;
-
-			Image imgRate = null;
-			if (allowRate) {
-				if (ROW_HOVER) {
-					TableRow row = cell.getTableRow();
-					boolean rowHasMouse = (row instanceof TableRowCore)
-							? ((TableRowCore) row).isMouseOver() : false;
-					if (rowHasMouse && userRating == -1) {
-						showAverage = false;
-						showRateActionIcon = true;
-					}
-				}
-				boolean cellHasMouse = (cell instanceof TableCellCore)
-						? ((TableCellCore) cell).isMouseOver() : false;
-
-				switch (userRating) {
-					case -2: // waiting
-						imgRate = imgWait;
-						break;
-
-					case -3:
-						if (disabled) {
-							imgRate = imgRateMeButtonDisabled;
-						}
-						break;
-
-					case -1: // unrated
-						boolean mouseIn = useButton && cellHasMouse;
-						if ((useButton && !mouseIn) || disabled) {
-							imgRate = imgRateMeButton;
-						} else {
-							if (cellHasMouse) {
-								showAverage = false;
-								showRateActionIcon = true;
-							}
-							switch (hoveringOn) {
-								case 0:
-									imgRate = imgRateMeDown;
-									break;
-								case 1:
-									imgRate = imgRateMeUp;
-									break;
-								default:
-									imgRate = imgRateMe;
-							}
-						}
-						break;
-
-					case 0:
-						imgRate = useButton ? imgDown : imgDownSmall;
-						break;
-
-					case 1:
-						imgRate = useButton ? imgUp : imgUpSmall;
-						break;
-				}
-			}
-
-			areaUserRating = null;
-
-			if (showAverage) {
-				if (showRateActionIcon) {
-					try {
-						gcImage.setAlpha(40);
-					} catch (Exception e) {
-						// Ignore ERROR_NO_GRAPHICS_LIBRARY error or any others
-					}
-				}
-				Rectangle r = img.getBounds();
-				int bigTextStyle = SWT.TOP | SWT.RIGHT;
-				int smallTextStyle = SWT.RIGHT;
-				if (imgRate != null && (userRating >= 0 || userRating == -2)) {
-					//smallTextStyle = SWT.RIGHT;
-					Rectangle imgRateDrawArea = imgRate.getBounds();
-					imgRateDrawArea.x = r.width - 53;
-					imgRateDrawArea.y = (height - 14) / 2
-							- (imgRate.getBounds().height / 2);
-					gcImage.drawImage(imgRate, imgRateDrawArea.x, imgRateDrawArea.y);
-					if (userRating >= 0) {
-						areaUserRating = imgRateDrawArea;
-					}
-				}
-
-				r.y += 2;
-				r.height -= 14;
-
-				if (font == null) {
-					// no sync required, SWT is on single thread
-					FontData[] fontData = gcImage.getFont().getFontData();
-					fontData[0].setStyle(SWT.BOLD);
-					// we can do a few more pixels because we have no text hanging below baseline
-					Utils.getFontHeightFromPX(gcImage.getDevice(), fontData, gcImage, 22);
-					font = new Font(Display.getDefault(), fontData);
-				}
-
-				gcImage.setFont(font);
-				try {
-					gcImage.setTextAntialias(SWT.ON);
-				} catch (Exception e) {
-					// Ignore ERROR_NO_GRAPHICS_LIBRARY error or any others
-				}
-
-				SWTSkinProperties skinProperties = SWTSkinFactory.getInstance().getSkinProperties();
-
-				int[] cbg = cell.getBackground();
-				HSLColor hsl = new HSLColor();
-				hsl.initHSLbyRGB(cbg[0], cbg[1], cbg[2]);
-				hsl.setLuminence(hsl.getLuminence() - 10);
-				Color color2 = ColorCache.getColor(Display.getDefault(), hsl.getRed(),
-						hsl.getGreen(), hsl.getBlue());
-
-				if (color2 != null) {
-					gcImage.setForeground(color2);
-				}
-
-				GCStringPrinter.printString(gcImage, rating, r, true, false,
-						bigTextStyle);
-
-				Color color1 = ColorCache.getColor(Display.getDefault(),
-						GlobalRatingUtils.getColor(torrent));
-				if (color1 == null) {
-					color1 = skinProperties.getColor("color.row.fg");
-					if (color1 == null) {
-						color1 = ColorCache.getColor(gcImage.getDevice(),
-								cell.getForeground());
-					}
-				}
-
-				r = img.getBounds();
-				r.width -= 2;
-				r.height -= 14;
-				if (color1 != null) {
-					gcImage.setForeground(color1);
-				}
-				GCStringPrinter.printString(gcImage, rating, r, true, false,
-						bigTextStyle);
-
-				if (count > 0) {
-					if (smallFont == null) {
-						gcImage.setFont(null);
-						// no sync required, SWT is on single thread
-						FontData[] fontData = gcImage.getFont().getFontData();
-						fontData[0].setHeight(Utils.pixelsToPoint(9,
-								Display.getDefault().getDPI().y));
-						smallFont = new Font(Display.getDefault(), fontData);
-					}
-
-					gcImage.setFont(smallFont);
-					try {
-						gcImage.setTextAntialias(SWT.DEFAULT);
-					} catch (Exception e) {
-						// Ignore ERROR_NO_GRAPHICS_LIBRARY error or any others
-					}
-
-					Rectangle rectDrawRatings = img.getBounds();
-					//rectDrawRatings.height -= 4;
-					rectDrawRatings.width -= 3;
-					rectDrawRatings.y = r.y + 20;
-					String sRatingInfo = count + " ratings";
-					Point ratingInfoExtent = gcImage.textExtent(sRatingInfo);
-					if (ratingInfoExtent.x > rectDrawRatings.width) {
-						sRatingInfo = DisplayFormatters.formatDecimal(count / 1000.0, 1)
-								+ "k ratings";
-						ratingInfoExtent = gcImage.textExtent(sRatingInfo);
-						if (ratingInfoExtent.x > rectDrawRatings.width) {
-							sRatingInfo = (count / 1000) + "k ratings";
-						}
-					}
-					GCStringPrinter.printString(gcImage, sRatingInfo, rectDrawRatings,
-							true, false, SWT.TOP | smallTextStyle);
-				}
-
-				if (showRateActionIcon) {
-					try {
-						gcImage.setAlpha(255);
-					} catch (Exception e) {
-						// Ignore ERROR_NO_GRAPHICS_LIBRARY error or any others
-					}
-				}
-			}
-
-			if (showRateActionIcon) {
-				if (imgRate != null) {
-					Point drawPos = getRateIconPos(imgRate.getBounds(), width, height);
-					gcImage.drawImage(imgRate, drawPos.x, drawPos.y);
-					areaUserRating = imgRate.getBounds();
-					areaUserRating.x = drawPos.x;
-					areaUserRating.y = drawPos.y;
-				}
-			}
-
-			gcImage.dispose();
-
-			Graphic graphic = new UISWTGraphicImpl(img);
-
-			disposeOldImage(cell);
-
-			cell.setGraphic(graphic);
-		}
-
-		/**
-		 * 
-		 */
-		private void disposeOldImage(TableCell cell) {
-			Graphic oldGraphic = cell.getGraphic();
-			if (oldGraphic instanceof UISWTGraphic) {
-				Image image = ((UISWTGraphic) oldGraphic).getImage();
-				if (image != null && !image.isDisposed()) {
-					image.dispose();
-				}
-			}
-		}
-
-		public void cellMouseTrigger(final TableCellMouseEvent event) {
-			if (dm == null) {
-				return;
-			}
-
-			TableRow tableRow = event.cell.getTableRow();
-			if (tableRow == null) {
-				rowMouseTrigger(event, event.cell);
-			}
-
-			if (disabled) {
-				return;
-			}
-
-			if (event.eventType == TableCellMouseEvent.EVENT_MOUSEUP
-					&& event.button == 2) {
-				DownloadManager dm = getDM(event.cell.getDataSource());
-				if (dm == null) {
-					return;
-				}
-
-				TOTorrent torrent = dm.getTorrent();
-				PlatformRatingMessenger.updateGlobalRating(torrent, 0);
-				Utils.beep();
-			}
-
-			// rating!
-			if (!allowRate) {
-				return;
-			}
-
-			if (event.eventType == TableCellMouseEvent.EVENT_MOUSEEXIT) {
-				hoveringOn = -1;
-			} else if (event.eventType == TableCellMouseEvent.EVENT_MOUSEMOVE) {
-				int userRating = PlatformTorrentUtils.getUserRating(dm.getTorrent());
-
-				if (userRating == -1) {
-					int cellWidth = event.cell.getWidth();
-					int cellHeight = event.cell.getHeight();
-					Point drawPos = getRateIconPos(boundsRateMe, cellWidth, cellHeight);
-					drawPos.x = event.x - drawPos.x;
-					drawPos.y = event.y - drawPos.y;
-					if (drawPos.x >= 0 && drawPos.y >= 0
-							&& drawPos.x < boundsRateMe.width
-							&& drawPos.y < boundsRateMe.height) {
-						final int value = (drawPos.x < (boundsRateMe.height - drawPos.y + 1))
-								? 1 : 0;
-
-						if (hoveringOn != value) {
-							hoveringOn = value;
-							if ((cell instanceof TableCellCore)) {
-								((TableCellCore) event.cell).setCursorID(SWT.CURSOR_HAND);
-							}
-							refresh(event.cell, true);
-						}
-					} else {
-						if (hoveringOn != -1) {
-							hoveringOn = -1;
-							if (cell instanceof TableCellCore) {
-								((TableCellCore) event.cell).setCursorID(SWT.CURSOR_ARROW);
-							}
-							refresh(event.cell, true);
-						}
-					}
-				} else {
-					if (cell instanceof TableCellCore) {
-						if (areaUserRating != null
-								&& areaUserRating.contains(event.x, event.y)) {
-							((TableCellCore) event.cell).setCursorID(SWT.CURSOR_HAND);
-							event.cell.setToolTip("Click to remove your rating");
-						} else {
-							((TableCellCore) event.cell).setCursorID(SWT.CURSOR_ARROW);
-							event.cell.setToolTip(null);
-						}
-					}
-				}
-			}
-
-			if (event.eventType == TableCellMouseEvent.EVENT_MOUSEENTER
-					|| event.eventType == TableCellMouseEvent.EVENT_MOUSEEXIT) {
-				refresh(event.cell, true);
-				return;
-			}
-
-			if (event.eventType != TableCellMouseEvent.EVENT_MOUSEDOWN
-					&& event.eventType != TableCellMouseEvent.EVENT_MOUSEUP) {
-				return;
-			}
-
-			// only first button
-			if (event.button != 1) {
-				return;
-			}
-
-			DownloadManager dm = getDM(event.cell.getDataSource());
-			if (dm == null) {
-				return;
-			}
-
-			if (!PlatformTorrentUtils.isContent(dm.getTorrent(), true)) {
-				return;
-			}
-
-			int userRating = PlatformTorrentUtils.getUserRating(dm.getTorrent());
-
-			if (event.eventType == TableCellMouseEvent.EVENT_MOUSEDOWN) {
-				bMouseDowned = true;
-				return;
-			}
-
-			if (event.eventType == TableCellMouseEvent.EVENT_MOUSEUP && bMouseDowned) {
-				if (userRating == -1) {
-					// not set
-					int cellWidth = event.cell.getWidth();
-					int cellHeight = event.cell.getHeight();
-					Point drawPos = getRateIconPos(boundsRateMe, cellWidth, cellHeight);
-					drawPos.x = event.x - drawPos.x;
-					drawPos.y = event.y - drawPos.y;
-
-					if (drawPos.x >= 0 && drawPos.y >= 0
-							&& drawPos.x < boundsRateMe.width
-							&& drawPos.y < boundsRateMe.height) {
-						try {
-							final TOTorrent torrent = dm.getTorrent();
-							final int value = (drawPos.x < (boundsRateMe.height - drawPos.y + 1))
-									? 1 : 0;
-
-							PlatformRatingMessenger.setUserRating(torrent, value,
-									true, 0, new PlatformMessengerListener() {
-										public void replyReceived(PlatformMessage message,
-												String replyType, Map reply) {
-											refresh(event.cell, true);
-										}
-
-										public void messageSent(PlatformMessage message) {
-										}
-									});
-						} catch (Exception e) {
-							Debug.out(e);
-						}
-					}
-				} else if (areaUserRating != null
-						&& areaUserRating.contains(event.x, event.y)) {
-					// remove setting
-					try {
-						final TOTorrent torrent = dm.getTorrent();
-						if (userRating >= 0) {
-							refresh(event.cell, true);
-							PlatformRatingMessenger.setUserRating(torrent, -1, true,
-									0, new PlatformMessengerListener() {
-										public void replyReceived(PlatformMessage message,
-												String replyType, Map reply) {
-											refresh(event.cell, true);
-										}
-
-										public void messageSent(PlatformMessage message) {
-										}
-									});
-							event.skipCoreFunctionality = true;
-						}
-					} catch (Exception e) {
-						Debug.out(e);
-					}
-				}
-			}
-
-			bMouseDowned = false;
-		}
-
-		// @see org.gudy.azureus2.plugins.ui.tables.TableCellToolTipListener#cellHover(org.gudy.azureus2.plugins.ui.tables.TableCell)
-		public void cellHover(TableCell cell) {
-			if (Constants.isCVSVersion()) {
-				DownloadManager dm = getDM(cell.getDataSource());
-				if (dm == null) {
-					return;
-				}
-
-				TOTorrent torrent = dm.getTorrent();
-				long refreshOn = GlobalRatingUtils.getRefreshOn(torrent);
-				long diff = (refreshOn - SystemTime.getCurrentTime()) / 1000;
-				Object toolTip = cell.getToolTip();
-				if (!(toolTip instanceof String) || ((String) toolTip).startsWith("G.")) {
-					cell.setToolTip("G.Rating Auto Refreshes in "
-							+ TimeFormatter.format(diff));
-				}
-			}
-		}
-
-		// @see org.gudy.azureus2.plugins.ui.tables.TableCellToolTipListener#cellHoverComplete(org.gudy.azureus2.plugins.ui.tables.TableCell)
-		public void cellHoverComplete(TableCell cell) {
-			// TODO Auto-generated method stub
-
-		}
-
-		// @see org.gudy.azureus2.plugins.ui.tables.TableRowMouseListener#rowMouseTrigger(org.gudy.azureus2.plugins.ui.tables.TableRowMouseEvent)
-		public void rowMouseTrigger(TableRowMouseEvent event) {
-			TableCell cell = event.row.getTableCell(COLUMN_ID);
-			rowMouseTrigger(event, cell);
-		}
-
-		public void rowMouseTrigger(TableRowMouseEvent event, TableCell cell) {
-			boolean changed = false;
-			if (event.eventType == TableRowMouseEvent.EVENT_MOUSEENTER) {
-				changed = true;
-			} else if (event.eventType == TableRowMouseEvent.EVENT_MOUSEEXIT) {
-				changed = true;
-			}
-			if (changed) {
-				if (cell != null) {
-					refresh(cell, true);
-				} else if (event.row != null) {
-					((TableRowCore) event.row).invalidate();
-					((TableRowCore) event.row).redraw();
-				}
-			}
-		}
-
-		// @see com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger.RatingUpdateListener#ratingUpdated(com.aelitis.azureus.core.torrent.RatingInfoList)
-		public void ratingUpdated(RatingInfoList rating) {
-			if (dm == null) {
-				return;
-			}
-			try {
-				String hash = dm.getTorrent().getHashWrapper().toBase32String();
-				if (rating.hasHash(hash)) {
-					refresh(cell, true);
-				}
-			} catch (Exception e) {
-				// ignore
-			}
-		}
-
-		// @see org.gudy.azureus2.plugins.ui.tables.TableCellVisibilityListener#cellVisibilityChanged(org.gudy.azureus2.plugins.ui.tables.TableCell, int)
-		public void cellVisibilityChanged(TableCell cell, int visibility) {
-			if (visibility == TableCellVisibilityListener.VISIBILITY_SHOWN) {
-				PlatformRatingMessenger.addListener(this);
-			} else if (visibility == TableCellVisibilityListener.VISIBILITY_HIDDEN) {
-				PlatformRatingMessenger.removeListener(this);
-			}
-		}
-	}
-
-	public boolean useButton() {
-		return useButton;
-	}
-
-	public void setUseButton(boolean useButton) {
-		this.useButton = useButton;
-	}
-
-	public void setDisabled(boolean disabled) {
-		this.disabled = disabled;
-		imgRateMeButton = disabled ? imgRateMeButtonDisabled
-				: imgRateMeButtonEnabled;
-		this.invalidateCells();
-	}
-
-	private DownloadManager getDM(Object ds) {
-		DownloadManager dm = null;
-		if (ds instanceof DownloadManager) {
-			dm = (DownloadManager) ds;
-		} else if (ds instanceof VuzeActivitiesEntry) {
-			dm = ((VuzeActivitiesEntry) ds).getDownloadManger();
-		}
-		return dm;
-	}
-
-	private Point getRateIconPos(Rectangle imgBounds, int cellWidth,
-			int cellHeight) {
-		int x;
-		int y = imgBounds.height == cellHeight ? 0
-				: (cellHeight - imgBounds.height) / 2;
-		if (useButton) {
-			x = imgBounds.width == cellWidth ? 0 : (cellWidth - imgBounds.width) / 2;
-		} else {
-			x = cellWidth - imgBounds.width;
-		}
-		return new Point(x, y);
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnRateUpDown.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnRateUpDown.java
deleted file mode 100644
index 612ca2d..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnRateUpDown.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Created on Jun 16, 2006 2:41:08 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import java.util.Map;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.ui.swt.plugins.UISWTGraphic;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.core.messenger.PlatformMessage;
-import com.aelitis.azureus.core.messenger.PlatformMessengerListener;
-import com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.Graphic;
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Jun 16, 2006
- *
- * TODO: Implement
- */
-public class ColumnRateUpDown
-	extends CoreTableColumn
-	implements TableCellAddedListener, TableCellRefreshListener,
-	TableCellMouseListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-	public static final String COLUMN_ID = "RateIt";
-
-	private static final String ID_ICON_RATE = "icon.rate.library";
-	
-	private static final String ID_ICON_RATE_UP = "icon.rate.library.up";
-	
-	private static final String ID_ICON_RATE_DOWN = "icon.rate.library.down";
-	
-	private UISWTGraphicImpl graphicRate;
-	
-	private UISWTGraphicImpl graphicRateDown;
-	
-	private UISWTGraphicImpl graphicRateUp;
-	
-	private UISWTGraphicImpl graphicsWait[];
-	
-	private Rectangle boundsRate;
-
-	private static int width = 50;
-
-	private boolean useButton = false;
-
-	private boolean disabled = false;
-	
-
-	/**
-	 * 
-	 */
-	public ColumnRateUpDown(String sTableID) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_CENTER, width, sTableID);
-		initializeAsGraphic(width);
-		setWidthLimits(width, width);
-
-		Image img;
-		
-		img = ImageLoader.getInstance().getImage(ID_ICON_RATE);
-		graphicRate = new UISWTGraphicImpl(img);
-		
-		img = ImageLoader.getInstance().getImage(ID_ICON_RATE_DOWN);
-		graphicRateDown = new UISWTGraphicImpl(img);
-		
-		img = ImageLoader.getInstance().getImage(ID_ICON_RATE_UP);
-		graphicRateUp = new UISWTGraphicImpl(img);
-		
-		boundsRate = img.getBounds();
-		
-		Image[] imgs = ImageLoader.getInstance().getImages("image.sidebar.vitality.dots");
-		graphicsWait = new UISWTGraphicImpl[imgs.length];
-		for(int i = 0 ; i < imgs.length  ;i++) {
-			graphicsWait[i] =  new UISWTGraphicImpl(imgs[i]);
-		}
-	}
-	
-	public void remove() {
-		super.remove();
-
-		ImageLoader imageLoader = ImageLoader.getInstance();
-		if (graphicRate != null) {
-			imageLoader.releaseImage(ID_ICON_RATE);
-		}
-		if (graphicRateDown != null) {
-			imageLoader.releaseImage(ID_ICON_RATE_DOWN); 
-		}
-		if (graphicRateUp != null) {
-			imageLoader.releaseImage(ID_ICON_RATE_UP); 
-		}
-	}
-
-	public void fillTableColumnInfo(TableColumnInfo info) {
-		info.addCategories(new String[] {
-			CAT_CONTENT,
-		});
-	}
-
-	public void cellAdded(TableCell cell) {
-		cell.setMarginWidth(0);
-		cell.setMarginHeight(0);
-	}
-
-	public void refresh(TableCell cell) {
-		
-		Object ds = cell.getDataSource();
-		TOTorrent torrent = null;
-		if (ds instanceof TOTorrent) {
-			torrent = (TOTorrent) ds;
-		} else if (ds instanceof DownloadManager) {
-			torrent = ((DownloadManager) ds).getTorrent();
-			if (!PlatformTorrentUtils.isContentProgressive(torrent)
-					&& !((DownloadManager) ds).isDownloadComplete(false)) {
-				return;
-			}
-		}
-
-		if (torrent == null) {
-			return;
-		}
-		if (!PlatformTorrentUtils.isContent(torrent, true)) {
-			return;
-		}
-
-		int rating = PlatformTorrentUtils.getUserRating(torrent);
-
-		if (!cell.setSortValue(rating) && cell.isValid()) {
-			if(rating != -2) {
-				return;
-			}
-		}
-		
-		
-		
-		if (!cell.isShown()) {
-			return;
-		}
-		
-		UISWTGraphic graphic;
-		switch (rating) {
-			case -2: // waiting
-				int i = TableCellRefresher.getRefreshIndex(1, graphicsWait.length);
-				graphic = graphicsWait[i];
-				TableCellRefresher.addCell(this,cell);
-				break;
-
-			case -1: // unrated
-				graphic = graphicRate;
-				break;
-
-			case 0:
-				graphic = graphicRateDown;
-				break;
-
-			case 1:
-				graphic = graphicRateUp;
-				break;
-
-			default:
-				graphic = null;
-		}
-
-		cell.setGraphic(graphic);
-		
-		if ( !disabled && graphic != null && cell instanceof TableCellSWT ){
-			
-			((TableCellSWT)cell).setCursorID(SWT.CURSOR_HAND);
-		}
-	}
-
-	TableRow previousSelection = null;
-
-	public void cellMouseTrigger(final TableCellMouseEvent event) {
-		if (disabled) {
-			return;
-		}
-		
-		Object ds = event.cell.getDataSource();
-		TOTorrent torrent0 = null;
-		if (ds instanceof TOTorrent) {
-			torrent0 = (TOTorrent) ds;
-		} else if (ds instanceof DownloadManager) {
-			torrent0 = ((DownloadManager) ds).getTorrent();
-			if (!PlatformTorrentUtils.isContentProgressive(torrent0)
-					&& !((DownloadManager) ds).isDownloadComplete(false)) {
-				return;
-			}
-		}
-
-		if (torrent0 == null) {
-			return;
-		}
-
-		final TOTorrent torrent = torrent0;
-
-		// only first button
-		if (event.button != 1) {
-			return;
-		}
-
-
-		if (!PlatformTorrentUtils.isContent(torrent, true)) {
-			return;
-		}
-
-
-		if (event.eventType == TableCellMouseEvent.EVENT_MOUSEUP ) {
-
-			//By default, let's cancel the setting
-			boolean cancel = true;
-
-			// Are we in the graphics area? (and not canceling)
-			int cellWidth = event.cell.getWidth();
-			int cellHeight = event.cell.getHeight();
-			int x = event.x - ((cellWidth - boundsRate.width) / 2);
-			int y = event.y - ((cellHeight - boundsRate.height) / 2);
-
-			Graphic currentGraphic = event.cell.getGraphic();
-			
-			if (x >= 0 && y >= 0 && x < boundsRate.width
-					&& y < boundsRate.height &&  (graphicRate.equals(currentGraphic) || graphicRateUp.equals(currentGraphic) || graphicRateDown.equals(currentGraphic)) ) {
-				//The event is within the graphic, are we on a non-transparent pixel ?
-				int alpha = graphicRate.getImage().getImageData().getAlpha(x,y);
-				if(alpha > 0) {
-					try {
-						cancel = false;
-						final int value = (x < (boundsRate.width / 2)) ? 0 : 1;
-						int previousValue = PlatformTorrentUtils.getUserRating(torrent);
-						//Changing the value
-						if(value != previousValue) {
-							
-							PlatformRatingMessenger.setUserRating(torrent, value, true, 0,
-									new PlatformMessengerListener() {
-										public void replyReceived(PlatformMessage message,
-												String replyType, Map reply) {
-											refresh(event.cell);
-										}
-		
-										public void messageSent(PlatformMessage message) {
-										}
-									});
-							refresh(event.cell);
-						}
-					} catch (Exception e) {
-						Debug.out(e);
-					}
-				}
-			}
-			
-			 if(cancel) {
-				// remove setting
-				try {
-					final int oldValue = PlatformTorrentUtils.getUserRating(torrent);
-					if (oldValue == -2 || oldValue == -1) {
-						return;
-					}
-					PlatformRatingMessenger.setUserRating(torrent, -1, true, 0,
-							new PlatformMessengerListener() {
-								public void replyReceived(PlatformMessage message,
-										String replyType, Map reply) {
-									refresh(event.cell);
-								}
-
-								public void messageSent(PlatformMessage message) {
-								}
-							});
-					refresh(event.cell);
-				} catch (Exception e) {
-					Debug.out(e);
-				}
-			}
-		}
-	}
-
-	public boolean useButton() {
-		return useButton;
-	}
-
-	public void setUseButton(boolean useButton) {
-		this.useButton = useButton;
-	}
-
-	public void setDisabled(boolean disabled) {
-		this.disabled = disabled;
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnRatingGlobal.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnRatingGlobal.java
deleted file mode 100644
index b1bbfa6..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnRatingGlobal.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Created on Jun 16, 2006 2:41:08 PM
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.Display;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.util.DisplayFormatters;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger;
-import com.aelitis.azureus.core.messenger.config.RatingUpdateListener2;
-import com.aelitis.azureus.core.torrent.GlobalRatingUtils;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.core.torrent.RatingInfoList;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * A column that displays rating info like <code>ColumnRate</code> in a simple manner;
- * this column does not provide any actions such as mouse hover, mouse enter, etc... 
- * 
- * @author khai
- *
- */
-public class ColumnRatingGlobal
-	extends CoreTableColumn
-	implements TableCellAddedListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-	public static final String COLUMN_ID = "Rating_global";
-
-	public static final int COLUMN_WIDTH = 60;
-
-	public void fillTableColumnInfo(TableColumnInfo info) {
-		info.addCategories(new String[] { CAT_CONTENT });
-	}
-
-	private static Font font = null;
-
-	private static Font smallFont = null;
-
-	/**
-	 * 
-	 */
-	public ColumnRatingGlobal(String sTableID) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_LEAD, COLUMN_WIDTH, sTableID);
-		initialize(ALIGN_LEAD, POSITION_INVISIBLE, COLUMN_WIDTH);
-	}
-
-	public void cellAdded(TableCell cell) {
-		PlatformRatingMessenger.setGlobalRatingUpdateDelayed(false);
-		new Cell(cell);
-	}
-
-	private class Cell
-		implements TableCellSWTPaintListener, TableCellDisposeListener,
-		RatingUpdateListener2, TableCellVisibilityListener, TableCellRefreshListener
-	{
-		String rating = "--";
-
-		private DownloadManager dm;
-
-		private TableCell cell;
-
-		public Cell(final TableCell cell) {
-			this.cell = cell;
-			PlatformRatingMessenger.addListener(this);
-			cell.addListeners(this);
-			cell.setMarginWidth(2);
-
-			dm = getDM(cell.getDataSource());
-			if (dm != null) {
-				boolean isContent = PlatformTorrentUtils.isContent(dm.getTorrent(),
-						true);
-				if (!isContent) {
-					rating = "";
-					return;
-				}
-			}
-		}
-		
-		// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
-		public void refresh(TableCell cell) {
-			if (!cell.isValid()) {
-				setSortValue(cell);
-			}
-		}
-
-		/**
-		 * @param cell2
-		 *
-		 * @since 4.0.0.3
-		 */
-		private void setSortValue(TableCell cell) {
-			dm = getDM(cell.getDataSource());
-			if (dm == null) {
-				return;
-			}
-			TOTorrent torrent = dm.getTorrent();
-			if (torrent == null) {
-				return;
-			}
-			long count = GlobalRatingUtils.getCount(torrent);
-			String rating = GlobalRatingUtils.getRatingString(torrent);
-			if (rating == null) {
-				rating = "0";
-			}
-			int userRating = PlatformTorrentUtils.getUserRating(dm.getTorrent());
-
-			try {
-				float val = Float.parseFloat(rating) * 1000000 + count;
-				val = (val * 10) + (userRating + 3);
-				cell.setSortValue(val);
-			} catch (Exception e) {
-				cell.setSortValue(count > 0 ? new Float(count) : null);
-			}
-		}
-
-		public void dispose(TableCell cell) {
-			PlatformRatingMessenger.removeListener(this);
-			//disposeOldImage(cell);
-		}
-
-		// @see org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener#cellPaint(org.eclipse.swt.graphics.GC, org.gudy.azureus2.plugins.ui.tables.TableCell)
-		public void cellPaint(GC gcImage, TableCellSWT cell) {
-		//public void refresh(final TableCell cell, final boolean force) {
-
-			if (cell.isDisposed()) {
-				return;
-			}
-			DownloadManager newDM = getDM(cell.getDataSource());
-			if (dm == null || newDM != dm) {
-				if (newDM == null) {
-					return;
-				}
-				dm = newDM;
-			}
-
-			DownloadManager dm = getDM(cell.getDataSource());
-			if (dm == null) {
-				return;
-			}
-
-			TOTorrent torrent = dm.getTorrent();
-			String rating = GlobalRatingUtils.getRatingString(torrent);
-			long count = GlobalRatingUtils.getCount(torrent);
-			int userRating = PlatformTorrentUtils.getUserRating(dm.getTorrent());
-
-			boolean b;
-			try {
-				float val = Float.parseFloat(rating) * 1000000 + count;
-				val = (val * 10) + (userRating + 3);
-				b = !cell.setSortValue(val);
-			} catch (Exception e) {
-				b = !cell.setSortValue(count > 0 ? new Float(count) : null);
-			}
-
-			int width = cell.getWidth();
-			int height = cell.getHeight();
-			if (width <= 0 || height <= 0) {
-				return;
-			}
-
-			/*
-			 * Creates a blank image to paint the rating on top of
-			 */
-//			Graphic bgGraphic = cell.getBackgroundGraphic();
-//			Image img;
-//			if (bgGraphic instanceof UISWTGraphic) {
-//				img = ((UISWTGraphic) bgGraphic).getImage();
-//			} else {
-//				img = new Image(Display.getDefault(), width, height);
-//			}
-//			GC gcImage = new GC(img);
-			Rectangle r = cell.getBounds(); // img.getBounds();
-			
-			if (r.height < 30) {
-				GCStringPrinter.printString(gcImage, rating, r, true, false, SWT.RIGHT);
-				return;
-			}
-			
-			int bigTextStyle = SWT.TOP | SWT.RIGHT;
-			int smallTextStyle = SWT.RIGHT;
-
-			if (font == null) {
-				// no sync required, SWT is on single thread
-				FontData[] fontData = gcImage.getFont().getFontData();
-				//fontData[0].setStyle(SWT.BOLD);
-				// we can do a few more pixels because we have no text hanging below baseline
-				Utils.getFontHeightFromPX(gcImage.getDevice(), fontData, gcImage, 20);
-				font = new Font(Display.getDefault(), fontData);
-			}
-
-			gcImage.setFont(font);
-
-			try {
-				//				gcImage.setTextAntialias(SWT.ON);
-			} catch (Exception e) {
-				// Ignore ERROR_NO_GRAPHICS_LIBRARY error or any others
-			}
-
-			Color color1 = ColorCache.getColor(Display.getDefault(),
-					GlobalRatingUtils.getColor(torrent));
-			if (color1 == null) {
-				color1 = ColorCache.getColor(gcImage.getDevice(), cell.getForeground());
-			}
-
-			//r = img.getBounds();
-
-			if (color1 != null) {
-				gcImage.setForeground(color1);
-			}
-
-			GCStringPrinter.printString(gcImage, rating, r, true, false, bigTextStyle);
-
-			if (count > 0) {
-				if (smallFont == null) {
-					gcImage.setFont(null);
-					// no sync required, SWT is on single thread
-					FontData[] fontData = gcImage.getFont().getFontData();
-					fontData[0].setHeight(Utils.pixelsToPoint(9,
-							Display.getDefault().getDPI().y));
-					smallFont = new Font(Display.getDefault(), fontData);
-				}
-
-				gcImage.setFont(smallFont);
-				try {
-					//					gcImage.setTextAntialias(SWT.ON);
-				} catch (Exception e) {
-					// Ignore ERROR_NO_GRAPHICS_LIBRARY error or any others
-				}
-
-				//Rectangle rectDrawRatings = new Rectangle(0, 0, width, height);
-				//rectDrawRatings.y = r.y + 21;
-				r.y += 20;
-				String sRatingInfo = count + " ratings";
-				Point ratingInfoExtent = gcImage.textExtent(sRatingInfo);
-				if (ratingInfoExtent.x > r.width) {
-					sRatingInfo = DisplayFormatters.formatDecimal(count / 1000.0, 1)
-							+ "k ratings";
-					ratingInfoExtent = gcImage.textExtent(sRatingInfo);
-					if (ratingInfoExtent.x > r.width) {
-						sRatingInfo = (count / 1000) + "k ratings";
-					}
-				}
-				GCStringPrinter.printString(gcImage, sRatingInfo, r,
-						true, false, SWT.TOP | smallTextStyle);
-			}
-
-			//Graphic graphic = new UISWTGraphicImpl(img);
-
-			//disposeOldImage(cell);
-
-			//cell.setGraphic(graphic);
-
-			//gcImage.dispose();
-
-		}
-
-		/**
-		 * 
-		 *
-		private void disposeOldImage(TableCell cell) {
-			Graphic oldGraphic = cell.getGraphic();
-			if (oldGraphic instanceof UISWTGraphic) {
-				Image image = ((UISWTGraphic) oldGraphic).getImage();
-				if (image != null && !image.isDisposed()) {
-					image.dispose();
-				}
-			}
-		}
-		*/
-
-		// @see com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger.RatingUpdateListener#ratingUpdated(com.aelitis.azureus.core.torrent.RatingInfoList)
-		public void ratingUpdated(RatingInfoList rating) {
-			if (dm == null) {
-				return;
-			}
-			try {
-				String hash = dm.getTorrent().getHashWrapper().toBase32String();
-				if (rating.hasHash(hash)) {
-					setSortValue(cell);
-					cell.invalidate();
-				}
-			} catch (Exception e) {
-				// ignore
-			}
-		}
-
-		// @see org.gudy.azureus2.plugins.ui.tables.TableCellVisibilityListener#cellVisibilityChanged(org.gudy.azureus2.plugins.ui.tables.TableCell, int)
-		public void cellVisibilityChanged(TableCell cell, int visibility) {
-			if (visibility == TableCellVisibilityListener.VISIBILITY_SHOWN) {
-				PlatformRatingMessenger.addListener(this);
-			} else if (visibility == TableCellVisibilityListener.VISIBILITY_HIDDEN) {
-				PlatformRatingMessenger.removeListener(this);
-			}
-		}
-
-	}
-
-	private DownloadManager getDM(Object ds) {
-		DownloadManager dm = null;
-		if (ds instanceof DownloadManager) {
-			dm = (DownloadManager) ds;
-		} else if (ds instanceof VuzeActivitiesEntry) {
-			dm = ((VuzeActivitiesEntry) ds).getDownloadManger();
-		}
-		return dm;
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbAndName.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbAndName.java
new file mode 100644
index 0000000..38c3632
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbAndName.java
@@ -0,0 +1,301 @@
+/*
+ * File    : NameItem.java
+ * Created : 24 nov. 2003
+ * By      : Olivier
+ *
+ * Copyright (C) 2004, 2005, 2006 Aelitis SAS, All rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details ( see the LICENSE file ).
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * AELITIS, SAS au capital de 46,603.30 euros,
+ * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
+ */
+
+package com.aelitis.azureus.ui.swt.columns.torrent;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.ui.UIInputReceiver;
+import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
+import org.gudy.azureus2.plugins.ui.menus.MenuItem;
+import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
+import org.gudy.azureus2.plugins.ui.tables.*;
+import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
+import org.gudy.azureus2.ui.swt.debug.ObfusticateCellText;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
+import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
+import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+import com.aelitis.azureus.ui.swt.utils.TorrentUIUtilsV3;
+import com.aelitis.azureus.ui.swt.utils.TorrentUIUtilsV3.ContentImageLoadedListener;
+
+/** Torrent name cell for My Torrents.
+ *
+ * @author Olivier
+ * @author TuxPaper (2004/Apr/17: modified to TableCellAdapter)
+ */
+public class ColumnThumbAndName
+	extends CoreTableColumn
+	implements TableCellLightRefreshListener, ObfusticateCellText,
+	TableCellDisposeListener, TableCellSWTPaintListener
+{
+	public static final Class DATASOURCE_TYPE = Download.class;
+
+	public static final String COLUMN_ID = "name";
+
+	private boolean showIcon;
+
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_ESSENTIAL,
+			CAT_CONTENT
+		});
+	}
+
+	/**
+	 * 
+	 * @param sTableID
+	 */
+	public ColumnThumbAndName(String sTableID) {
+		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_LEAD, 250, sTableID);
+		setObfustication(true);
+		setRefreshInterval(INTERVAL_LIVE);
+		initializeAsGraphic(250);
+		setMinWidth(100);
+
+		TableContextMenuItem menuItem = addContextMenuItem("MyTorrentsView.menu.rename.displayed");
+		menuItem.addMultiListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				if (target == null) {
+					return;
+				}
+				Object[] o = (Object[]) target;
+				for (Object object : o) {
+					if (object instanceof DownloadManager) {
+						final DownloadManager dm = (DownloadManager) object;
+						String msg_key_prefix = "MyTorrentsView.menu.rename.displayed.enter.";
+
+						SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
+								msg_key_prefix + "title", msg_key_prefix + "message");
+						entryWindow.setPreenteredText(dm.getDisplayName(), false);
+						entryWindow.prompt(new UIInputReceiverListener() {
+							public void UIInputReceiverClosed(UIInputReceiver entryWindow) {
+								if (!entryWindow.hasSubmittedInput()) {
+									return;
+								}
+								String value = entryWindow.getSubmittedInput();
+								if (value != null && value.length() > 0) {
+									dm.getDownloadState().setDisplayName(value);
+								}
+							}
+						});
+					}
+				}
+			}
+		});
+
+		COConfigurationManager.addAndFireParameterListener(
+				"NameColumn.showProgramIcon", new ParameterListener() {
+					public void parameterChanged(String parameterName) {
+						setShowIcon(COConfigurationManager.getBooleanParameter("NameColumn.showProgramIcon"));
+					}
+				});
+	}
+
+	public void refresh(TableCell cell) {
+		refresh(cell, false);
+	}
+
+	public void refresh(TableCell cell, boolean sortOnlyRefresh) {
+		if (sortOnlyRefresh) {
+			String name = null;
+			DownloadManager dm = (DownloadManager) cell.getDataSource();
+			if (dm != null) {
+				name = dm.getDisplayName();
+			}
+			if (name == null) {
+				name = "";
+			}
+			
+			cell.setSortValue(name);
+		}
+	}
+
+	public void cellPaint(GC gc, final TableCellSWT cell) {
+		Object ds = cell.getDataSource();
+
+		Rectangle cellBounds = cell.getBounds();
+
+		Image[] imgThumbnail = TorrentUIUtilsV3.getContentImage(ds,
+				cellBounds.height >= 20,
+				new ContentImageLoadedListener() {
+					public void contentImageLoaded(Image image, boolean wasReturned) {
+						if (!wasReturned) {
+							// this may be triggered many times, so only invalidate and don't
+							// force a refresh()
+							cell.invalidate();
+						}
+					}
+				});
+
+		if (imgThumbnail == null) {
+			// don't need to release a null image
+			return;
+		}
+		
+
+		if (cellBounds.height > 30) {
+			cellBounds.y += 1;
+			cellBounds.height -= 3;
+		}
+		Rectangle imgBounds = imgThumbnail[0].getBounds();
+
+		int dstWidth;
+		int dstHeight;
+		if (imgBounds.height > cellBounds.height) {
+			dstHeight = cellBounds.height;
+			dstWidth = imgBounds.width * cellBounds.height / imgBounds.height;
+		} else if (imgBounds.width > cellBounds.width) {
+			dstWidth = cellBounds.width - 4;
+			dstHeight = imgBounds.height * cellBounds.width / imgBounds.width;
+		} else {
+			dstWidth = imgBounds.width;
+			dstHeight = imgBounds.height;
+		}
+
+		if (cellBounds.height <= 18) {
+			dstWidth = Math.min(dstWidth, cellBounds.height);
+			dstHeight = Math.min(dstHeight, cellBounds.height);
+			if (imgBounds.width > 16) {
+				cellBounds.y++;
+				dstHeight -= 2;
+			}
+		}
+		
+		try {
+			gc.setAdvanced(true);
+			gc.setInterpolation(SWT.HIGH);
+		} catch (Exception e) {
+		}
+		int x = cellBounds.x;
+		int textX = x + dstWidth + 3;
+		int minWidth = dstHeight * 7 / 4;
+		int imgPad = 0;
+		if (dstHeight > 25) {
+  		if (dstWidth < minWidth) {
+  			imgPad = ((minWidth - dstWidth + 1) / 2);
+  			x = cellBounds.x + imgPad;
+  			textX = cellBounds.x + minWidth + 3;
+  		}
+		}
+		if (cellBounds.width - dstWidth - (imgPad * 2) < 100 && dstHeight > 18) {
+			dstWidth = Math.min(32, dstHeight);
+			x = cellBounds.x + ((32 - dstWidth + 1) / 2);
+			dstHeight = imgBounds.height * dstWidth / imgBounds.width;
+			textX = cellBounds.x + dstWidth + 3;
+		}
+		int y = cellBounds.y + ((cellBounds.height - dstHeight + 1) / 2);
+		if (dstWidth > 0 && dstHeight > 0 && !imgBounds.isEmpty()) {
+			Rectangle dst = new Rectangle(x, y, dstWidth, dstHeight);
+			Rectangle lastClipping = gc.getClipping();
+			try {
+				gc.setClipping(cellBounds);
+
+				for (int i = 0; i < imgThumbnail.length; i++) {
+					Image image = imgThumbnail[i];
+					if (image == null || image.isDisposed()) {
+						continue;
+					}
+					Rectangle srcBounds = image.getBounds();
+					if (i == 0) {
+						int w = dstWidth;
+						int h = dstHeight;
+						if (imgThumbnail.length > 1) {
+							w = w * 9 / 10;
+							h = h * 9 / 10;
+						}
+						gc.drawImage(image, srcBounds.x, srcBounds.y, srcBounds.width,
+								srcBounds.height, x, y, w, h);
+					} else {
+						int w = dstWidth * 3 / 8;
+						int h = dstHeight * 3 / 8;
+						gc.drawImage(image, srcBounds.x, srcBounds.y, srcBounds.width,
+								srcBounds.height, x + dstWidth - w, y + dstHeight - h, w, h);
+					}
+				}
+			} catch (Exception e) {
+				Debug.out(e);
+			} finally {
+				gc.setClipping(lastClipping);
+			}
+		}
+
+		String name = null;
+		DownloadManager dm = (DownloadManager) cell.getDataSource();
+		if (dm != null)
+			name = dm.getDisplayName();
+		if (name == null)
+			name = "";
+
+		GCStringPrinter.printString(gc, name, new Rectangle(textX,
+				cellBounds.y, cellBounds.x + cellBounds.width - textX, cellBounds.height),
+				true, true, SWT.WRAP);
+
+		TorrentUIUtilsV3.releaseContentImage(ds);
+	}
+
+	public String getObfusticatedText(TableCell cell) {
+		String name = null;
+		DownloadManager dm = (DownloadManager) cell.getDataSource();
+		if (dm != null) {
+			name = dm.toString();
+			int i = name.indexOf('#');
+			if (i > 0) {
+				name = name.substring(i + 1);
+			}
+		}
+
+		if (name == null)
+			name = "";
+		return name;
+	}
+
+	public void dispose(TableCell cell) {
+
+	}
+
+	/**
+	 * @param showIcon the showIcon to set
+	 */
+	public void setShowIcon(boolean showIcon) {
+		this.showIcon = showIcon;
+	}
+
+	/**
+	 * @return the showIcon
+	 */
+	public boolean isShowIcon() {
+		return showIcon;
+	}
+
+}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbnail.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbnail.java
index 9bb2891..1540345 100644
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbnail.java
+++ b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbnail.java
@@ -142,7 +142,7 @@ public class ColumnThumbnail
 
 		Rectangle cellBounds = cell.getBounds();
 
-		Image imgThumbnail = TorrentUIUtilsV3.getContentImage(ds,
+		Image[] imgThumbnail = TorrentUIUtilsV3.getContentImage(ds,
 				cellBounds.width >= 20 && cellBounds.height >= 20,
 				new ContentImageLoadedListener() {
 					public void contentImageLoaded(Image image, boolean wasReturned) {
@@ -164,36 +164,16 @@ public class ColumnThumbnail
 			cellBounds.height -= 4;
 		}
 
-		Rectangle imgBounds = imgThumbnail.getBounds();
-		Rectangle srcBounds = new Rectangle(imgBounds.x, imgBounds.y,
-				imgBounds.width, imgBounds.height);
+		Rectangle imgBounds = imgThumbnail[0].getBounds();
 
 		int dstWidth;
 		int dstHeight;
-		if (imgBounds.width > cellBounds.width
-				|| imgBounds.height > cellBounds.height) {
+		if (imgBounds.height > cellBounds.height) {
+			dstHeight = cellBounds.height;
+			dstWidth = imgBounds.width * cellBounds.height / imgBounds.height;
+		} else if (imgBounds.width > cellBounds.width)  {
 			dstWidth = cellBounds.width - 4;
 			dstHeight = imgBounds.height * cellBounds.width / imgBounds.width;
-			if (cellBounds.height < 30) {
-				cellBounds.y += 1;
-				cellBounds.height -= 1;
-				
-				if (dstWidth > cellBounds.height * 5) {
-					dstHeight = cellBounds.height;
-					dstWidth = imgBounds.width * dstHeight / imgBounds.height;
-				}
-			}
-			
-			/*
-			int trim = (int) (imgBounds.width * 0.2);
-			if (imgBounds.width - cellBounds.width > trim) {
-				srcBounds.x += trim;
-				srcBounds.width -= trim * 2;
-				trim = (int) (imgBounds.height * 0.2);
-				srcBounds.y += trim;
-				srcBounds.height -= trim * 2;
-			}
-			*/
 		} else {
 			dstWidth = imgBounds.width;
 			dstHeight = imgBounds.height;
@@ -212,8 +192,25 @@ public class ColumnThumbnail
 			try {
 				gc.setClipping(cellBounds);
 
-				gc.drawImage(imgThumbnail, srcBounds.x, srcBounds.y, srcBounds.width,
-						srcBounds.height, x, y, dstWidth, dstHeight);
+				for (int i = 0; i < imgThumbnail.length; i++) {
+					Image image = imgThumbnail[i];
+					Rectangle srcBounds = image.getBounds();
+					if (i == 0) {
+						int w = dstWidth;
+						int h = dstHeight;
+						if (imgThumbnail.length > 1) {
+							w = w * 9 / 10;
+							h = h * 9 / 10;
+						}
+  					gc.drawImage(image, srcBounds.x, srcBounds.y, srcBounds.width,
+  							srcBounds.height, x, y, w, h);
+					} else {
+						int w = dstWidth * 3 / 8;
+						int h = dstHeight * 3 / 8;
+						gc.drawImage(image, srcBounds.x, srcBounds.y, srcBounds.width,
+								srcBounds.height, x + dstWidth - w, y + dstHeight - h, w, h);
+					}
+				}
 			} catch (Exception e) {
 				Debug.out(e);
 			} finally {
@@ -227,13 +224,13 @@ public class ColumnThumbnail
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellToolTipListener#cellHover(org.gudy.azureus2.plugins.ui.tables.TableCell)
 	public void cellHover(TableCell cell) {
 		final Object ds = cell.getDataSource();
-		Image imgThumbnail = TorrentUIUtilsV3.getContentImage(ds, true, new ContentImageLoadedListener() {
+		Image[] imgThumbnail = TorrentUIUtilsV3.getContentImage(ds, true, new ContentImageLoadedListener() {
 			public void contentImageLoaded(Image image, boolean wasReturned) {
 				TorrentUIUtilsV3.releaseContentImage(ds);
 			}
 		});
 
-		cell.setToolTip(imgThumbnail);
+		cell.setToolTip(imgThumbnail == null ? null : imgThumbnail[0]);
 	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellToolTipListener#cellHoverComplete(org.gudy.azureus2.plugins.ui.tables.TableCell)
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnTitle.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnTitle.java
deleted file mode 100644
index 4d178be..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnTitle.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/**
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.program.Program;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.debug.ObfusticateCellText;
-import org.gudy.azureus2.ui.swt.plugins.UISWTGraphic;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
-import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
-import org.gudy.azureus2.ui.swt.shells.GCStringPrinter.URLInfo;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.ui.common.table.TableRowCore;
-import com.aelitis.azureus.ui.skin.SkinConstants;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinFactory;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinProperties;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-import com.aelitis.azureus.util.DataSourceUtils;
-import com.aelitis.azureus.util.UrlFilter;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.Graphic;
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Oct 10, 2006
- *
- */
-public class ColumnTitle
-	extends CoreTableColumn
-	implements TableCellRefreshListener, ObfusticateCellText,
-	TableCellMouseMoveListener, TableCellDisposeListener, TableCellVisibilityListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-	public static String COLUMN_ID = "name";
-
-	public void fillTableColumnInfo(TableColumnInfo info) {
-		info.addCategories(new String[] { CAT_CONTENT, CAT_ESSENTIAL });
-	}
-
-	public static boolean SHOW_EXT_INFO = false;
-	
-	public static boolean LINKIFY = false;
-
-	static public String s = "";
-
-	private Color colorLinkNormal;
-
-	private Color colorLinkHover;
-
-	/** Default Constructor */
-	public ColumnTitle(String sTableID) {
-		super(COLUMN_ID, POSITION_INVISIBLE, 250, sTableID);
-		setMinWidth(70);
-		setObfustication(true);
-		if (LINKIFY) {
-			setType(TableColumn.TYPE_GRAPHIC);
-
-			SWTSkinProperties skinProperties = SWTSkinFactory.getInstance().getSkinProperties();
-			colorLinkNormal = skinProperties.getColor("color.links.normal");
-			colorLinkHover = skinProperties.getColor("color.links.hover");
-		} else {
-			// Mouse movement, cell disposal and visibility monitoring only needed
-			// if we are making a graphic.  These get added automatically, so remove
-			// them
-			removeCellMouseMoveListener(this);
-			removeCellDisposeListener(this);
-			removeCellVisibilityListener(this);
-		}
-	}
-	
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellDisposeListener#dispose(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void dispose(TableCell cell) {
-		disposeExisting(cell);
-	}
-
-	public void refresh(TableCell cell) {
-		String name = null;
-		DownloadManager dm = (DownloadManager) cell.getDataSource();
-		if (dm != null) {
-			name = PlatformTorrentUtils.getContentTitle2(dm);
-		}
-		if (name == null) {
-			name = "";
-		}
-
-		if (!cell.setSortValue(name) && cell.isValid()) {
-			return;
-		}
-
-		if (!cell.isShown()) {
-			return;
-		}
-		
-		if (!LINKIFY) {
-			cell.setText(name);
-			return;
-		}
-
-		if (SHOW_EXT_INFO && name.length() > 0) {
-			String path = dm.getDownloadState().getPrimaryFile();
-			if (path != null) {
-				int pos = path.lastIndexOf('.');
-				if (pos >= 0) {
-					String ext = path.substring(pos);
-					Program program = Program.findProgram(ext);
-					if (program != null) {
-						ext += " (" + program.getName() + ")";
-					}
-					name += "\n"
-							+ MessageText.getString("TableColumn.header.name.ext",
-									new String[] {
-										ext
-									});
-				}
-			}
-		}
-
-		Graphic graphic = cell.getBackgroundGraphic();
-		if (!(graphic instanceof UISWTGraphic)) {
-			cell.setText(name);
-		}
-
-		Image img = ((UISWTGraphic) graphic).getImage();
-		if (img == null) {
-			return;
-		}
-
-		String sText = name;
-		if (DataSourceUtils.isPlatformContent(dm)) {
-			try {
-				sText = "<A HREF=\""
-						+ DataSourceUtils.getContentNetwork(dm).getContentDetailsService(
-								dm.getTorrent().getHashWrapper().toBase32String(), null)
-						+ "\">" + name + "</A>";
-			} catch (Exception e) {
-				Debug.out(e);
-			}
-		}
-
-		GC gc = new GC(img);
-		try {
-			gc.setForeground(ColorCache.getColor(gc.getDevice(), cell.getForeground()));
-			GCStringPrinter stringPrinter = new GCStringPrinter(gc, sText,
-					img.getBounds(), true, true, SWT.LEFT | SWT.WRAP);
-			stringPrinter.calculateMetrics();
-
-			if (stringPrinter.hasHitUrl()) {
-				TableRow row = cell.getTableRow();
-				if (row instanceof TableRowCore) {
-					((TableRowCore) row).setData("titleStringPrinter", stringPrinter);
-				}
-				int[] mouseOfs = cell.getMouseOffset();
-				if (mouseOfs != null
-						&& stringPrinter.getHitUrl(mouseOfs[0], mouseOfs[1]) != null) {
-					stringPrinter.setUrlColor(colorLinkHover);
-				} else {
-					stringPrinter.setUrlColor(colorLinkNormal);
-				}
-			}
-
-			stringPrinter.printString();
-		} finally {
-			gc.dispose();
-		}
-
-		disposeExisting(cell);
-		cell.setGraphic(new UISWTGraphicImpl(img));
-	}
-
-	private void disposeExisting(TableCell cell) {
-		Graphic oldGraphic = cell.getGraphic();
-		//log(cell, oldGraphic);
-		if (oldGraphic instanceof UISWTGraphic) {
-			Image oldImage = ((UISWTGraphic) oldGraphic).getImage();
-			if (oldImage != null && !oldImage.isDisposed()) {
-				//log(cell, "dispose");
-				cell.setGraphic(null);
-				oldImage.dispose();
-			}
-		}
-	}
-
-	public String getObfusticatedText(TableCell cell) {
-		String name = null;
-		DownloadManager dm = (DownloadManager) cell.getDataSource();
-		if (dm != null) {
-			name = dm.toString();
-			int i = name.indexOf('#');
-			if (i > 0) {
-				name = name.substring(i + 1);
-			}
-		}
-
-		if (name == null) {
-			name = "";
-		}
-		return name;
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellMouseListener#cellMouseTrigger(org.gudy.azureus2.plugins.ui.tables.TableCellMouseEvent)
-	public void cellMouseTrigger(TableCellMouseEvent event) {
-		if (!(event.cell instanceof TableCellSWT)) {
-			return;
-		}
-		TableRow row = event.cell.getTableRow();
-		if (row instanceof TableRowCore) {
-			GCStringPrinter stringPrinter = (GCStringPrinter) ((TableRowCore) row).getData("titleStringPrinter");
-			if (stringPrinter != null) {
-				URLInfo hitUrl = stringPrinter.getHitUrl(event.x, event.y);
-
-				int oldCursorID = ((TableCellSWT) event.cell).getCursorID();
-				int newCursorID = oldCursorID;
-				if (hitUrl != null) {
-					if (event.eventType == TableCellMouseEvent.EVENT_MOUSEUP
-							&& event.button == 1) {
-						if (UrlFilter.getInstance().urlIsBlocked(hitUrl.url)) {
-							Utils.launch(hitUrl.url);
-						} else {
-							UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
-							if (uif != null) {
-								uif.viewURL(hitUrl.url, SkinConstants.VIEWID_BROWSER_BROWSE,
-										"column.title");
-								return;
-							}
-						}
-					}
-
-					newCursorID = SWT.CURSOR_HAND;
-				} else {
-					newCursorID = SWT.CURSOR_ARROW;
-				}
-				if (oldCursorID != newCursorID) {
-					((TableCellSWT) event.cell).setCursorID(newCursorID);
-					event.cell.invalidate();
-					((TableCellSWT) event.cell).refreshAsync();
-				}
-			}
-		}
-	}
-	
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellVisibilityListener#cellVisibilityChanged(org.gudy.azureus2.plugins.ui.tables.TableCell, int)
-	public void cellVisibilityChanged(TableCell cell, int visibility) {
-		if (visibility == TableCellVisibilityListener.VISIBILITY_HIDDEN) {
-			disposeExisting(cell);
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnVideoLength.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnVideoLength.java
deleted file mode 100644
index 975af34..0000000
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnVideoLength.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Created on Sep 28, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.ui.swt.columns.torrent;
-
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.util.DisplayFormatters;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.util.DataSourceUtils;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.tables.TableCell;
-import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
-import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
-
-/**
- * @author TuxPaper
- * @created Sep 28, 2008
- *
- */
-public class ColumnVideoLength
-	extends CoreTableColumn
-	implements TableCellRefreshListener
-{
-	public static final Class DATASOURCE_TYPE = Download.class;
-
-	public static final String COLUMN_ID = "videoLength";
-
-	public void fillTableColumnInfo(TableColumnInfo info) {
-		info.addCategories(new String[] { CAT_CONTENT });
-	}
-
-	private static final int WIDTH = 100;
-
-	/**
-	 * @param name
-	 * @param alignment
-	 * @param position
-	 * @param width
-	 * @param tableID
-	 */
-	public ColumnVideoLength(String tableID) {
-		super(COLUMN_ID, WIDTH, tableID);
-		setAlignment(ALIGN_TRAIL);
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void refresh(TableCell cell) {
-		TOTorrent torrent = DataSourceUtils.getTorrent(cell.getDataSource());
-		
-		long value = PlatformTorrentUtils.getContentVideoRunningTime(torrent);
-		if (!cell.setSortValue(value) && cell.isValid()) {
-			return;
-		}
-		cell.setText(DisplayFormatters.formatTime(value * 1000));
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/utils/TableColumnCreatorV3.java b/com/aelitis/azureus/ui/swt/columns/utils/TableColumnCreatorV3.java
index 079f6d2..d04d022 100644
--- a/com/aelitis/azureus/ui/swt/columns/utils/TableColumnCreatorV3.java
+++ b/com/aelitis/azureus/ui/swt/columns/utils/TableColumnCreatorV3.java
@@ -40,21 +40,20 @@ public class TableColumnCreatorV3
 			boolean big) {
 		final String[] defaultVisibleOrder = {
 			ColumnUnopened.COLUMN_ID,
-			ColumnAzProduct.COLUMN_ID,
-			ColumnThumbnail.COLUMN_ID,
-			NameItem.COLUMN_ID,
+			ColumnThumbAndName.COLUMN_ID,
+			"RatingColumn",
 			"azsubs.ui.column.subs",
 			SizeItem.COLUMN_ID,
-			ColumnQuality.COLUMN_ID,
-			ColumnInfo.COLUMN_ID,
-			ColumnRateUpDown.COLUMN_ID,
 			StatusItem.COLUMN_ID,
 			ShareRatioItem.COLUMN_ID,
 			DateCompletedItem.COLUMN_ID,
 		};
 
 		TableColumnManager tcManager = TableColumnManager.getInstance();
-		Map mapTCs = tcManager.getTableColumnsAsMap(Download.class, tableID);
+		Map<String, TableColumnCore> mapTCs = tcManager.getTableColumnsAsMap(
+				Download.class, tableID);
+		
+		tcManager.setDefaultColumnNames(tableID, defaultVisibleOrder);
 
 		if (!tcManager.loadTableColumnSettings(Download.class, tableID)
 				|| areNoneVisible(mapTCs)) {
@@ -64,10 +63,6 @@ public class TableColumnCreatorV3
 				tcManager.setDefaultSortColumnName(tableID, DateCompletedItem.COLUMN_ID);
 				tc.setSortAscending(false);
 			}
-			NameItem tcName = (NameItem) mapTCs.get(NameItem.COLUMN_ID);
-			if (tcName != null) {
-				tcName.setWidth(140);
-			}
 		}
 
 		// special changes
@@ -79,9 +74,9 @@ public class TableColumnCreatorV3
 				tcStatusItem.setShowTrackerErrors( true );
 			}
 		}
-		NameItem tcNameItem = (NameItem) mapTCs.get(NameItem.COLUMN_ID);
-		if (tcNameItem != null) {
-			tcNameItem.setShowIcon(false);
+		ColumnThumbAndName tcColumnNameIcon = (ColumnThumbAndName) mapTCs.get(ColumnThumbAndName.COLUMN_ID);
+		if (tcColumnNameIcon != null) {
+			tcColumnNameIcon.setShowIcon(false);
 		}
 		if (big) {
 			ShareRatioItem tcShareRatioItem = (ShareRatioItem) mapTCs.get(ShareRatioItem.COLUMN_ID);
@@ -91,40 +86,34 @@ public class TableColumnCreatorV3
 			}
 		}
 
-		return (TableColumnCore[]) mapTCs.values().toArray(new TableColumnCore[0]);
+		return mapTCs.values().toArray(new TableColumnCore[0]);
 	}
 
 	public static TableColumnCore[] createIncompleteDM(String tableID, boolean big) {
 		final String[] defaultVisibleOrder = {
-			ColumnAzProduct.COLUMN_ID,
-			ColumnThumbnail.COLUMN_ID,
-			NameItem.COLUMN_ID,
+			ColumnThumbAndName.COLUMN_ID,
 			"azsubs.ui.column.subs",
 			SizeItem.COLUMN_ID,
-			ColumnQuality.COLUMN_ID,
-			ColumnInfo.COLUMN_ID,
 			ColumnProgressETA.COLUMN_ID,
 			SeedsItem.COLUMN_ID,
 			PeersItem.COLUMN_ID,
 		};
 
 		TableColumnManager tcManager = TableColumnManager.getInstance();
-		Map mapTCs = tcManager.getTableColumnsAsMap(DownloadTypeIncomplete.class,
-				tableID);
+		Map<String, TableColumnCore> mapTCs = tcManager.getTableColumnsAsMap(
+				DownloadTypeIncomplete.class, tableID);
+
+		tcManager.setDefaultColumnNames(tableID, defaultVisibleOrder);
 
 		if (!tcManager.loadTableColumnSettings(DownloadTypeIncomplete.class,
 				tableID)
 				|| areNoneVisible(mapTCs)) {
 			setVisibility(mapTCs, defaultVisibleOrder);
-			NameItem tc = (NameItem) mapTCs.get(NameItem.COLUMN_ID);
+			ColumnThumbAndName tc = (ColumnThumbAndName) mapTCs.get(ColumnThumbAndName.COLUMN_ID);
 			if (tc != null) {
-				tcManager.setDefaultSortColumnName(tableID, NameItem.COLUMN_ID);
+				tcManager.setDefaultSortColumnName(tableID, ColumnThumbAndName.COLUMN_ID);
 				tc.setSortAscending(true);
 			}
-			NameItem tcName = (NameItem) mapTCs.get(NameItem.COLUMN_ID);
-			if (tcName != null) {
-				tcName.setWidth(220);
-			}
 		}
 
 		// special changes
@@ -135,9 +124,9 @@ public class TableColumnCreatorV3
 				tcStatusItem.setChangeCellFG(false);
 			}
 		}
-		NameItem tcNameItem = (NameItem) mapTCs.get(NameItem.COLUMN_ID);
-		if (tcNameItem != null) {
-			tcNameItem.setShowIcon(false);
+		ColumnThumbAndName tcColumnNameIcon = (ColumnThumbAndName) mapTCs.get(ColumnThumbAndName.COLUMN_ID);
+		if (tcColumnNameIcon != null) {
+			tcColumnNameIcon.setShowIcon(false);
 		}
 		
 		if (big) {
@@ -148,7 +137,7 @@ public class TableColumnCreatorV3
 			}
 		}
 
-		return (TableColumnCore[]) mapTCs.values().toArray(new TableColumnCore[0]);
+		return mapTCs.values().toArray(new TableColumnCore[0]);
 	}
 
 	/**
@@ -174,14 +163,10 @@ public class TableColumnCreatorV3
 	public static TableColumnCore[] createCompleteDM(String tableID, boolean big) {
 		final String[] defaultVisibleOrder = {
 			ColumnUnopened.COLUMN_ID,
-			ColumnAzProduct.COLUMN_ID,
-			ColumnThumbnail.COLUMN_ID,
-			NameItem.COLUMN_ID,
+			ColumnThumbAndName.COLUMN_ID,
+			"RatingColumn",
 			"azsubs.ui.column.subs",
 			SizeItem.COLUMN_ID,
-			ColumnQuality.COLUMN_ID,
-			ColumnInfo.COLUMN_ID,
-			ColumnRateUpDown.COLUMN_ID,
 			StatusItem.COLUMN_ID,
 			ShareRatioItem.COLUMN_ID,
 			DateCompletedItem.COLUMN_ID,
@@ -191,6 +176,8 @@ public class TableColumnCreatorV3
 		Map mapTCs = tcManager.getTableColumnsAsMap(DownloadTypeComplete.class,
 				tableID);
 
+		tcManager.setDefaultColumnNames(tableID, defaultVisibleOrder);
+
 		if (!tcManager.loadTableColumnSettings(DownloadTypeComplete.class, tableID)
 				|| areNoneVisible(mapTCs)) {
 			setVisibility(mapTCs, defaultVisibleOrder);
@@ -199,10 +186,6 @@ public class TableColumnCreatorV3
 				tcManager.setDefaultSortColumnName(tableID, DateCompletedItem.COLUMN_ID);
 				tc.setSortAscending(false);
 			}
-			NameItem tcName = (NameItem) mapTCs.get(NameItem.COLUMN_ID);
-			if (tcName != null) {
-				tcName.setWidth(140);
-			}
 		}
 
 		// special changes
@@ -213,9 +196,9 @@ public class TableColumnCreatorV3
 				tcStatusItem.setChangeCellFG(false);
 			}
 		}
-		NameItem tcNameItem = (NameItem) mapTCs.get(NameItem.COLUMN_ID);
-		if (tcNameItem != null) {
-			tcNameItem.setShowIcon(false);
+		ColumnThumbAndName tcColumnNameIcon = (ColumnThumbAndName) mapTCs.get(ColumnThumbAndName.COLUMN_ID);
+		if (tcColumnNameIcon != null) {
+			tcColumnNameIcon.setShowIcon(false);
 		}
 		if (big) {
 			ShareRatioItem tcShareRatioItem = (ShareRatioItem) mapTCs.get(ShareRatioItem.COLUMN_ID);
@@ -231,12 +214,9 @@ public class TableColumnCreatorV3
 	public static TableColumnCore[] createUnopenedDM(String tableID, boolean big) {
 		final String[] defaultVisibleOrder = {
 			ColumnUnopened.COLUMN_ID,
-			ColumnThumbnail.COLUMN_ID,
-			NameItem.COLUMN_ID,
+			ColumnThumbAndName.COLUMN_ID,
 			"azsubs.ui.column.subs",
 			SizeItem.COLUMN_ID,
-			ColumnQuality.COLUMN_ID,
-			ColumnInfo.COLUMN_ID,
 			StatusItem.COLUMN_ID,
 			DateCompletedItem.COLUMN_ID,
 		};
@@ -245,6 +225,8 @@ public class TableColumnCreatorV3
 		Map mapTCs = tcManager.getTableColumnsAsMap(DownloadTypeIncomplete.class,
 				tableID);
 
+		tcManager.setDefaultColumnNames(tableID, defaultVisibleOrder);
+
 		if (!tcManager.loadTableColumnSettings(DownloadTypeIncomplete.class,
 				tableID)
 				|| areNoneVisible(mapTCs)) {
@@ -254,10 +236,6 @@ public class TableColumnCreatorV3
 				tcManager.setDefaultSortColumnName(tableID, DateCompletedItem.COLUMN_ID);
 				tc.setSortAscending(false);
 			}
-			NameItem tcName = (NameItem) mapTCs.get(NameItem.COLUMN_ID);
-			if (tcName != null) {
-				tcName.setWidth(265);
-			}
 		}
 
 		// special changes
@@ -268,9 +246,9 @@ public class TableColumnCreatorV3
 				tcStatusItem.setChangeCellFG(false);
 			}
 		}
-		NameItem tcNameItem = (NameItem) mapTCs.get(NameItem.COLUMN_ID);
-		if (tcNameItem != null) {
-			tcNameItem.setShowIcon(false);
+		ColumnThumbAndName tcColumnNameIcon = (ColumnThumbAndName) mapTCs.get(ColumnThumbAndName.COLUMN_ID);
+		if (tcColumnNameIcon != null) {
+			tcColumnNameIcon.setShowIcon(false);
 		}
 		if (big) {
 			ShareRatioItem tcShareRatioItem = (ShareRatioItem) mapTCs.get(ShareRatioItem.COLUMN_ID);
@@ -295,6 +273,8 @@ public class TableColumnCreatorV3
 		Map mapTCs = tcManager.getTableColumnsAsMap(VuzeActivitiesEntry.class,
 				tableID);
 
+		tcManager.setDefaultColumnNames(tableID, defaultVisibleOrder);
+
 		if (!tcManager.loadTableColumnSettings(VuzeActivitiesEntry.class, tableID)
 				|| areNoneVisible(mapTCs)) {
 			setVisibility(mapTCs, defaultVisibleOrder);
@@ -317,7 +297,6 @@ public class TableColumnCreatorV3
 		final String[] defaultVisibleOrder = {
 			ColumnActivityNew.COLUMN_ID,
 			ColumnActivityType.COLUMN_ID,
-			ColumnActivityAvatar.COLUMN_ID,
 			ColumnActivityText.COLUMN_ID,
 			ColumnThumbnail.COLUMN_ID,
 			ColumnActivityActions.COLUMN_ID,
@@ -327,6 +306,8 @@ public class TableColumnCreatorV3
 		Map mapTCs = tcManager.getTableColumnsAsMap(VuzeActivitiesEntry.class,
 				tableID);
 
+		tcManager.setDefaultColumnNames(tableID, defaultVisibleOrder);
+
 		if (!tcManager.loadTableColumnSettings(VuzeActivitiesEntry.class, tableID)
 				|| areNoneVisible(mapTCs)) {
 			setVisibility(mapTCs, defaultVisibleOrder);
@@ -374,15 +355,10 @@ public class TableColumnCreatorV3
 		TableColumnCreator.initCoreColumns();
 
 		// short variable names to reduce wrapping
-		final Map c = new LightHashMap(7);
+		final Map<String, cInfo> c = new LightHashMap<String, cInfo>(7);
 
 		c.put(ColumnUnopened.COLUMN_ID, new cInfo(ColumnUnopened.class, ColumnUnopened.DATASOURCE_TYPE));
-		//c.put(ColumnThumbnail.COLUMN_ID, new cInfo(ColumnThumbnail.class, ColumnThumbnail.DATASOURCE_TYPE));
-		c.put(ColumnQuality.COLUMN_ID, new cInfo(ColumnQuality.class, ColumnQuality.DATASOURCE_TYPE));
-		c.put(ColumnInfo.COLUMN_ID, new cInfo(ColumnInfo.class, ColumnInfo.DATASOURCE_TYPE));
-		c.put(ColumnRateUpDown.COLUMN_ID, new cInfo(ColumnRateUpDown.class, ColumnRateUpDown.DATASOURCE_TYPE));
-		c.put(ColumnRatingGlobal.COLUMN_ID, new cInfo(ColumnRatingGlobal.class, ColumnRatingGlobal.DATASOURCE_TYPE));
-		c.put(ColumnVideoLength.COLUMN_ID, new cInfo(ColumnVideoLength.class, ColumnVideoLength.DATASOURCE_TYPE));
+		c.put(ColumnThumbAndName.COLUMN_ID, new cInfo(ColumnThumbAndName.class, ColumnThumbAndName.DATASOURCE_TYPE));
 		c.put(DateAddedItem.COLUMN_ID, new cInfo(DateAddedItem.class, DateAddedItem.DATASOURCE_TYPE));
 		c.put(DateCompletedItem.COLUMN_ID, new cInfo(DateCompletedItem.class, DateCompletedItem.DATASOURCE_TYPE));
 		c.put(ColumnProgressETA.COLUMN_ID, new cInfo(ColumnProgressETA.class, ColumnProgressETA.DATASOURCE_TYPE));
@@ -392,8 +368,6 @@ public class TableColumnCreatorV3
 		final Class ac = VuzeActivitiesEntry.class;
 
 		c.put(ColumnActivityNew.COLUMN_ID, new cInfo(ColumnActivityNew.class, ac));
-		c.put(ColumnActivityAvatar.COLUMN_ID, new cInfo(ColumnActivityAvatar.class,
-				ac));
 		c.put(ColumnActivityType.COLUMN_ID, new cInfo(ColumnActivityType.class, ac));
 		c.put(ColumnActivityText.COLUMN_ID, new cInfo(ColumnActivityText.class, ac));
 		c.put(ColumnActivityActions.COLUMN_ID, new cInfo(
@@ -403,12 +377,6 @@ public class TableColumnCreatorV3
 		c.put(ColumnThumbnail.COLUMN_ID, new cInfo(ColumnThumbnail.class,
 				new Class[] {
 					ac,
-					Download.class
-				}));
-		c.put(ColumnAzProduct.COLUMN_ID, new cInfo(ColumnAzProduct.class,
-				new Class[] {
-					ac,
-					Download.class
 				}));
 
 		// Core columns are implementors of TableColumn to save one class creation
@@ -421,7 +389,7 @@ public class TableColumnCreatorV3
 			// @see org.gudy.azureus2.ui.swt.views.table.TableColumnCoreCreationListener#createTableColumnCore(java.lang.Class, java.lang.String, java.lang.String)
 			public TableColumnCore createTableColumnCore(Class forDataSourceType,
 					String tableID, String columnID) {
-				cInfo info = (cInfo) c.get(columnID);
+				cInfo info = c.get(columnID);
 
 				try {
 					Constructor constructor = info.cla.getDeclaredConstructor(new Class[] {
@@ -442,9 +410,11 @@ public class TableColumnCreatorV3
 			}
 		};
 
-		for (Iterator iter = c.keySet().iterator(); iter.hasNext();) {
-			String id = (String) iter.next();
-			cInfo info = (cInfo) c.get(id);
+		tcManager.unregisterColumn(NameItem.DATASOURCE_TYPE, NameItem.COLUMN_ID, null);
+
+		for (Iterator<String> iter = c.keySet().iterator(); iter.hasNext();) {
+			String id = iter.next();
+			cInfo info = c.get(id);
 
 			for (int i = 0; i < info.forDataSourceTypes.length; i++) {
 				Class cla = info.forDataSourceTypes[i];
@@ -452,6 +422,7 @@ public class TableColumnCreatorV3
 				tcManager.registerColumn(cla, id, tcCreator);
 			}
 		}
+		
 
 	}
 
diff --git a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityActions.java b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityActions.java
index 6a72801..1f2bacd 100644
--- a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityActions.java
+++ b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityActions.java
@@ -18,42 +18,28 @@
 
 package com.aelitis.azureus.ui.swt.columns.vuzeactivity;
 
-import java.util.Map;
-
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.widgets.Display;
 
 import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.ui.tables.*;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.plugins.UISWTGraphic;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
 import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
 import org.gudy.azureus2.ui.swt.shells.GCStringPrinter.URLInfo;
 import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
 import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
-import com.aelitis.azureus.activities.VuzeActivitiesConstants;
 import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.activities.VuzeActivitiesEntryBuddyRequest;
-import com.aelitis.azureus.core.messenger.PlatformMessage;
-import com.aelitis.azureus.core.messenger.PlatformMessengerListener;
-import com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinFactory;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinProperties;
 import com.aelitis.azureus.ui.swt.views.skin.TorrentListViewsUtils;
 import com.aelitis.azureus.util.*;
 
-import org.gudy.azureus2.plugins.ui.Graphic;
-import org.gudy.azureus2.plugins.ui.tables.*;
-
 /**
  * @author TuxPaper
  * @created Sep 25, 2008
@@ -70,22 +56,6 @@ public class ColumnActivityActions
 
 	private Color colorLinkHover;
 
-	private boolean useButton = false;
-
-	private boolean mouseIn = false;
-
-	private boolean disabled = false;
-
-	private static UISWTGraphicImpl graphicRate;
-	
-	private static UISWTGraphicImpl graphicRateDown;
-	
-	private static UISWTGraphicImpl graphicRateUp;
-	
-	private static UISWTGraphicImpl graphicsWait[];
-	
-	private static Rectangle boundsRate;
-	
 	private static Font font = null;
 
 	/**
@@ -99,25 +69,6 @@ public class ColumnActivityActions
 		SWTSkinProperties skinProperties = SWTSkinFactory.getInstance().getSkinProperties();
 		colorLinkNormal = skinProperties.getColor("color.links.normal");
 		colorLinkHover = skinProperties.getColor("color.links.hover");
-
-		Image img;
-		
-		img = ImageLoader.getInstance().getImage("icon.rate.library");
-		graphicRate = new UISWTGraphicImpl(img);
-		
-		img = ImageLoader.getInstance().getImage("icon.rate.library.down");
-		graphicRateDown = new UISWTGraphicImpl(img);
-		
-		img = ImageLoader.getInstance().getImage("icon.rate.library.up");
-		graphicRateUp = new UISWTGraphicImpl(img);
-		
-		boundsRate = img.getBounds();
-		
-		Image[] imgs = ImageLoader.getInstance().getImages("image.sidebar.vitality.dots");
-		graphicsWait = new UISWTGraphicImpl[imgs.length];
-		for(int i = 0 ; i < imgs.length  ;i++) {
-			graphicsWait[i] =  new UISWTGraphicImpl(imgs[i]);
-		}
 	}
 
 	// @see org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener#cellPaint(org.eclipse.swt.graphics.GC, org.gudy.azureus2.ui.swt.views.table.TableCellSWT)
@@ -126,10 +77,6 @@ public class ColumnActivityActions
 		if (entry == null) {
 			return;
 		}
-		if (entry.getTypeID().equals(VuzeActivitiesConstants.TYPEID_RATING_REMINDER)) {
-			cellPaintForRate(gc, cell);
-			return;
-		}
 
 		String text = cell.getText();
 
@@ -187,72 +134,47 @@ public class ColumnActivityActions
 		
 		if(entry == null) return;
 		
-		if (VuzeActivitiesConstants.TYPEID_RATING_REMINDER.equals(entry.getTypeID()) ) {
-			TOTorrent torrent = DataSourceUtils.getTorrent(entry);
-			if (torrent == null) {
-				return;
-			}
-			int rating = PlatformTorrentUtils.getUserRating(torrent);
-
-			if (cell.setSortValue(rating)) {
-				((TableCellSWT) cell).redraw();
-			}
-			
-			return;
-		}
-
 		if (!cell.setSortValue(entry.getTypeID()) && cell.isValid()) {
 			return;
 		}
 
-		if (entry instanceof VuzeActivitiesEntryBuddyRequest) {
-			VuzeActivitiesEntryBuddyRequest br = (VuzeActivitiesEntryBuddyRequest) entry;
-			String urlAccept = br.getUrlAccept();
-			String text = "<A HREF=\"" + urlAccept + "\" TARGET=\"browse\">Accept</A>";
-			cell.setText(text);
-		} else {
-			DownloadManager dm = entry.getDownloadManger();
-			boolean canPlay = PlayUtils.canPlayDS(entry);
-			boolean canDL = dm == null && entry.getDownloadManger() == null
-					&& (entry.getTorrent() != null || entry.getAssetHash() != null);
-			boolean canRun = !canPlay && dm != null;
-			if (canRun && dm != null && !dm.getAssumedComplete()) {
-				canRun = false;
-			}
+		DownloadManager dm = entry.getDownloadManger();
+		boolean canPlay = PlayUtils.canPlayDS(entry);
+		boolean canDL = dm == null && entry.getDownloadManger() == null
+				&& (entry.getTorrent() != null || entry.getAssetHash() != null);
+		boolean canRun = !canPlay && dm != null;
+		if (canRun && dm != null && !dm.getAssumedComplete()) {
+			canRun = false;
+		}
 
-			StringBuffer sb = new StringBuffer();
-			if (canDL) {
-				if (sb.length() > 0) {
-					sb.append(" | ");
-				}
-				sb.append("<A HREF=\"download\">Download</A>");
+		StringBuffer sb = new StringBuffer();
+		if (canDL) {
+			if (sb.length() > 0) {
+				sb.append(" | ");
 			}
+			sb.append("<A HREF=\"download\">Download</A>");
+		}
 
-			if (canPlay) {
-				if (sb.length() > 0) {
-					sb.append(" | ");
-				}
-				sb.append("<A HREF=\"play\">Play</A>");
+		if (canPlay) {
+			if (sb.length() > 0) {
+				sb.append(" | ");
 			}
+			sb.append("<A HREF=\"play\">Play</A>");
+		}
 
-			if (canRun) {
-				if (sb.length() > 0) {
-					sb.append(", ");
-				}
-				sb.append("<A HREF=\"launch\">Launch</A>");
+		if (canRun) {
+			if (sb.length() > 0) {
+				sb.append(", ");
 			}
-
-			cell.setText(sb.toString());
+			sb.append("<A HREF=\"launch\">Launch</A>");
 		}
+
+		cell.setText(sb.toString());
 	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellMouseListener#cellMouseTrigger(org.gudy.azureus2.plugins.ui.tables.TableCellMouseEvent)
 	public void cellMouseTrigger(TableCellMouseEvent event) {
 		VuzeActivitiesEntry entry = (VuzeActivitiesEntry) event.cell.getDataSource();
-		if (entry.getTypeID().equals(VuzeActivitiesConstants.TYPEID_RATING_REMINDER)) {
-			cellMouseTriggerForRate(event);
-			return;
-		}
 
 		String tooltip = null;
 		boolean invalidateAndRefresh = false;
@@ -371,172 +293,6 @@ public class ColumnActivityActions
 
 	boolean bMouseDowned = false;
 
-	public void cellMouseTriggerForRate(final TableCellMouseEvent event) {
-		if (disabled) {
-			return;
-		}
-		TOTorrent torrent0 = DataSourceUtils.getTorrent(event.cell.getDataSource());
-
-		if (torrent0 == null) {
-			return;
-		}
-
-		if (useButton) {
-			if (event.eventType == TableCellMouseEvent.EVENT_MOUSEENTER) {
-				mouseIn = true;
-				refresh(event.cell);
-			} else if (event.eventType == TableCellMouseEvent.EVENT_MOUSEEXIT) {
-				mouseIn = false;
-				refresh(event.cell);
-			}
-		}
-
-		final TOTorrent torrent = torrent0;
-
-		// only first button
-		if (event.button != 1) {
-			return;
-		}
-
-		// no rating if row isn't selected yet
-		TableRow row = event.cell.getTableRow();
-		if (row != null && !row.isSelected()) {
-			return;
-		}
-
-		if (!PlatformTorrentUtils.isContent(torrent, true)) {
-			return;
-		}
-
-		if (event.eventType == TableCellMouseEvent.EVENT_MOUSEUP ) {
-
-			//By default, let's cancel the setting
-			boolean cancel = true;
-
-			// Are we in the graphics area? (and not canceling)
-			int cellWidth = event.cell.getWidth();
-			int cellHeight = event.cell.getHeight();
-			int x = event.x - ((cellWidth - boundsRate.width) / 2);
-			int y = event.y - ((cellHeight - boundsRate.height) / 2);
-
-			Graphic currentGraphic = event.cell.getGraphic();
-			
-			if (x >= 0 && y >= 0 && x < boundsRate.width
-					&& y < boundsRate.height ) {
-				
-				int middle = boundsRate.width / 2 + 2;
-				boolean hit = x < middle - 2 || x > middle + 2;
-				//The event is within the graphic, are we on a non-transparent pixel ?
-				//boolean hit = graphicRate.getImage().getImageData().getAlpha(x,y) > 0;
-				if(hit) {
-					try {
-						cancel = false;
-						final int value = (x < (boundsRate.width / 2)) ? 0 : 1;
-						int previousValue = PlatformTorrentUtils.getUserRating(torrent);
-						//Changing the value
-						if(value != previousValue) {
-							
-							PlatformRatingMessenger.setUserRating(torrent, value, true, 0,
-									new PlatformMessengerListener() {
-										public void replyReceived(PlatformMessage message,
-												String replyType, Map reply) {
-											refresh(event.cell);
-										}
-		
-										public void messageSent(PlatformMessage message) {
-										}
-									});
-							refresh(event.cell);
-						}
-					} catch (Exception e) {
-						Debug.out(e);
-					}
-				}
-			} else {
-				cancel = false;
-			}
-			
-			 if(cancel) {
-				// remove setting
-				try {
-					final int oldValue = PlatformTorrentUtils.getUserRating(torrent);
-					if (oldValue == -2 || oldValue == -1) {
-						return;
-					}
-					PlatformRatingMessenger.setUserRating(torrent, -1, true, 0,
-							new PlatformMessengerListener() {
-								public void replyReceived(PlatformMessage message,
-										String replyType, Map reply) {
-									refresh(event.cell);
-								}
-
-								public void messageSent(PlatformMessage message) {
-								}
-							});
-					refresh(event.cell);
-				} catch (Exception e) {
-					Debug.out(e);
-				}
-			}
-		}
-	}
-
-	public void cellPaintForRate(GC gc, TableCellSWT cell) {
-
-		Object ds = cell.getDataSource();
-		
-		TOTorrent torrent = DataSourceUtils.getTorrent(ds);
-
-		if (torrent == null) {
-			return;
-		}
-		if (!PlatformTorrentUtils.isContent(torrent, true)) {
-			return;
-		}
-
-		int rating = PlatformTorrentUtils.getUserRating(torrent);
-
-		/*if (!cell.setSortValue(rating) && cell.isValid()) {
-			if(rating != -2) {
-				return;
-			}
-		}*/
-		
-		
-		
-		if (!cell.isShown()) {
-			return;
-		}
-		
-		UISWTGraphic graphic;
-		switch (rating) {
-			case -2: // waiting
-				graphic = graphicsWait[0];
-				break;
-
-			case -1: // unrated
-				graphic = graphicRate;
-				break;
-
-			case 0:
-				graphic = graphicRateDown;
-				break;
-
-			case 1:
-				graphic = graphicRateUp;
-				break;
-
-			default:
-				graphic = null;
-		}
-
-		if(graphic != null) {
-			Rectangle drawBounds = getDrawBounds(cell);
-			gc.drawImage(graphic.getImage(), drawBounds.x + (drawBounds.width - boundsRate.width)
-					/ 2, drawBounds.y + (drawBounds.height - boundsRate.height) / 2);
-		}
-	}
-	
 	private Rectangle getDrawBounds(TableCellSWT cell) {
 		Rectangle bounds = cell.getBounds();
 		bounds.height -= 12;
diff --git a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityAvatar.java b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityAvatar.java
deleted file mode 100644
index 6bda1c9..0000000
--- a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityAvatar.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * Created on Sep 25, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.ui.swt.columns.vuzeactivity;
-
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.activities.VuzeActivitiesEntryBuddy;
-import com.aelitis.azureus.activities.VuzeActivitiesEntryBuddyLinkup;
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.ui.swt.buddy.VuzeBuddySWT;
-
-import org.gudy.azureus2.plugins.ui.tables.TableCell;
-import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
-
-/**
- * @author TuxPaper
- * @created Sep 25, 2008
- *
- */
-public class ColumnActivityAvatar
-	extends CoreTableColumn
-	implements TableCellSWTPaintListener, TableCellRefreshListener
-{
-	public static final String COLUMN_ID = "activityAvatar";
-
-	/**
-	 * @param name
-	 * @param tableID
-	 */
-	public ColumnActivityAvatar(String tableID) {
-		super(COLUMN_ID, 40, tableID);
-
-		initializeAsGraphic(40);
-	}
-
-	// @see org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener#cellPaint(org.eclipse.swt.graphics.GC, org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void cellPaint(GC gc, TableCellSWT cell) {
-		VuzeActivitiesEntry entry = (VuzeActivitiesEntry) cell.getDataSource();
-
-		if (entry instanceof VuzeActivitiesEntryBuddy) {
-
-			VuzeActivitiesEntryBuddy entryBuddy = (VuzeActivitiesEntryBuddy) entry;
-			VuzeBuddy buddy = entryBuddy.getBuddy();
-			if (buddy instanceof VuzeBuddySWT) {
-				VuzeBuddySWT buddySWT = (VuzeBuddySWT) buddy;
-				Image imgAvatar = buddySWT.getAvatarImage();
-
-				if (imgAvatar != null) {
-					Rectangle cellBounds = cell.getBounds();
-					Rectangle imgBounds = imgAvatar.getBounds();
-					int dstWidth = cellBounds.width - 4;
-					int dstHeight = dstWidth;
-					
-					try {
-						gc.setAdvanced(true);
-					} catch (Exception e) {
-						// ignore
-					}
-
-					gc.drawImage(imgAvatar, 0, 0, imgBounds.width, imgBounds.height,
-							cellBounds.x + ((cellBounds.width - dstWidth) / 2), cellBounds.y
-									+ ((cellBounds.height - dstWidth) / 2), dstWidth, dstHeight);
-					buddySWT.releaseAvatarImage(imgAvatar);
-				}
-			}
-
-		}
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void refresh(TableCell cell) {
-		VuzeActivitiesEntry entry = (VuzeActivitiesEntry) cell.getDataSource();
-
-		
-		if (entry instanceof VuzeActivitiesEntryBuddy) {
-			VuzeBuddy buddy = ((VuzeActivitiesEntryBuddy)entry).getBuddy();
-			cell.setSortValue(buddy == null ? null : buddy.getDisplayName());
-		} else {
-			cell.setSortValue(null);
-		}
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityNew.java b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityNew.java
index 9403afa..3ea7c48 100644
--- a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityNew.java
+++ b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityNew.java
@@ -57,6 +57,7 @@ public class ColumnActivityNew
 		super(COLUMN_ID, tableID);
 
 		initializeAsGraphic(WIDTH);
+		setAlignment(ALIGN_CENTER);
 		imgNew = ImageLoader.getInstance().getImage("image.activity.unread");
 		imgOld = ImageLoader.getInstance().getImage("image.activity.read");
 	}
diff --git a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityText.java b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityText.java
index 1c2a4ce..27449ea 100644
--- a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityText.java
+++ b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityText.java
@@ -28,13 +28,13 @@ import org.eclipse.swt.widgets.Display;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.shells.GCStringPrinter.URLInfo;
 import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
 import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.activities.VuzeActivitiesEntryContentShare;
 import com.aelitis.azureus.core.util.GeneralUtils;
 import com.aelitis.azureus.ui.skin.SkinConstants;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
@@ -165,10 +165,7 @@ public class ColumnActivityText
 			int newCursor;
 			if (hitUrl != null) {
 				if (event.eventType == TableCellMouseEvent.EVENT_MOUSEDOWN) {
-					if (VuzeActivitiesEntryContentShare.URL_USERMESSAGE.equals(hitUrl.url)) {
-						String userMessage = ((VuzeActivitiesEntryContentShare) entry).getUserMessage();
-						Utils.openMessageBox(null, SWT.OK, "", userMessage);
-					} else if (!UrlFilter.getInstance().urlCanRPC(hitUrl.url)) {
+					if (!UrlFilter.getInstance().urlCanRPC(hitUrl.url)) {
 						Utils.launch(hitUrl.url);
 					} else {
 						UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
@@ -184,8 +181,7 @@ public class ColumnActivityText
 				}
 
 				newCursor = SWT.CURSOR_HAND;
-				if (UrlFilter.getInstance().urlCanRPC(hitUrl.url)
-						|| VuzeActivitiesEntryContentShare.URL_USERMESSAGE.equals(hitUrl.url)) {
+				if (UrlFilter.getInstance().urlCanRPC(hitUrl.url)) {
 					try {
 						tooltip = hitUrl.title == null ? null : URLDecoder.decode(
 								hitUrl.title, "utf-8");
diff --git a/com/aelitis/azureus/ui/swt/content/RelatedContentUI.java b/com/aelitis/azureus/ui/swt/content/RelatedContentUI.java
index f664271..6e10c22 100644
--- a/com/aelitis/azureus/ui/swt/content/RelatedContentUI.java
+++ b/com/aelitis/azureus/ui/swt/content/RelatedContentUI.java
@@ -24,16 +24,15 @@ package com.aelitis.azureus.ui.swt.content;
 
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 
 import org.eclipse.swt.widgets.TreeItem;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.AsyncDispatcher;
 import org.gudy.azureus2.core3.util.ByteArrayHashMap;
 import org.gudy.azureus2.core3.util.ByteFormatter;
-import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.download.Download;
@@ -82,8 +81,19 @@ import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
 
 public class 
 RelatedContentUI 
-{	
-	private static final boolean	DISABLE_ALL_UI	= !Constants.isCVSVersion();
+{		
+	private static RelatedContentUI	singleton;
+	
+	public static synchronized RelatedContentUI
+	getSingleton()
+	{
+		if ( singleton == null ){
+			
+			singleton = new RelatedContentUI();
+		}
+		
+		return( singleton );
+	}
 	
 	private PluginInterface		plugin_interface;
 	private UIManager			ui_manager;
@@ -98,6 +108,8 @@ RelatedContentUI
 	
 	private ByteArrayHashMap<RCMItem>	rcm_item_map = new ByteArrayHashMap<RCMItem>();
 	
+	private AsyncDispatcher	async_dispatcher = new AsyncDispatcher();
+	
 	public 
 	RelatedContentUI()
 	{
@@ -192,7 +204,7 @@ RelatedContentUI
 		try{	
 			manager 	= RelatedContentManager.getSingleton();
 
-			if ( DISABLE_ALL_UI || !manager.isEnabled()){
+			if ( !manager.isUIEnabled()){
 				
 				return;
 			}
@@ -424,6 +436,8 @@ RelatedContentUI
 							main_view_info.getTitle(),
 							main_view_info, null, false, index  );
 					
+					main_sb_entry.setImageLeftID( "image.sidebar.rcm" );
+					
 					main_sb_entry.setDatasource(
 						new RelatedContentEnumerator()
 						{
@@ -571,22 +585,30 @@ RelatedContentUI
 	addSearch(
 		final Download		download )
 	{
-		synchronized( this ){
-				
-			Torrent	torrent = download.getTorrent();
-			
-			if ( torrent == null ){
-				
-				return;
-			}
+		Torrent	torrent = download.getTorrent();
+		
+		if ( torrent == null ){
 			
-			final byte[] hash = torrent.getHash();
+			return;
+		}
+		
+		final byte[] hash = torrent.getHash();
+		
+		addSearch( hash, download.getName());
+	}
+	
+	protected void
+	addSearch(
+		final byte[]		hash,
+		final String		name )
+	{
+		synchronized( this ){
 			
 			final RCMItem existing_si = rcm_item_map.get( hash );
 			
 			if (  existing_si == null ){
 	
-				final RCMItem new_si = new RCMItem( download, hash );
+				final RCMItem new_si = new RCMItem( hash );
 				
 				rcm_item_map.put( hash, new_si );
 				
@@ -603,7 +625,7 @@ RelatedContentUI
 									return;
 								}
 								
-								RCMView view = new RCMView( SideBar.SIDEBAR_SECTION_RELATED_CONTENT, download );
+								RCMView view = new RCMView( SideBar.SIDEBAR_SECTION_RELATED_CONTENT, name );
 								
 								new_si.setView( view );
 								
@@ -715,17 +737,17 @@ RelatedContentUI
 		implements 	ViewTitleInfo
 	{
 		private String			parent_key;
-		private Download		download;
+		private String			name;
 		
 		private int				num_unread;
 		
 		protected
 		RCMView(
 			String			_parent_key,
-			Download		_download )
+			String			_name )
 		{
 			parent_key	= _parent_key;
-			download	= _download;
+			name		= _name;
 		}
 		
 		public Object 
@@ -753,7 +775,7 @@ RelatedContentUI
 		public String
 		getTitle()
 		{
-			return( download.getName());
+			return( name );
 		}
 		
 		protected void
@@ -797,7 +819,6 @@ RelatedContentUI
 	RCMItem
 		implements RelatedContentEnumerator, SideBarCloseListener
 	{	
-		private Download			download;
 		private byte[]				hash;
 		
 		private RCMView				view;
@@ -817,10 +838,8 @@ RelatedContentUI
 		
 		protected
 		RCMItem(
-			Download	_download,
 			byte[]		_hash )
 		{
-			download	= _download;
 			hash		= _hash;
 		}
 		
@@ -842,7 +861,7 @@ RelatedContentUI
 				showIcon( spinner, null );
 				
 				manager.lookupContent(
-					download,
+					hash,
 					new RelatedContentLookupListener()
 					{
 						public void
@@ -860,7 +879,10 @@ RelatedContentUI
 								
 									for ( RelatedContent c: content ){
 									
-										content_list.add( c );
+										if ( !content_list.contains( c )){
+										
+											content_list.add( c );
+										}
 									}
 								}
 							}
@@ -914,23 +936,12 @@ RelatedContentUI
 			boolean deleted = false;
 			
 			synchronized( RCMItem.this ){
-				
-				Iterator<RelatedContent> it = content_list.iterator();
-				
-				while( it.hasNext()){
-					
-					RelatedContent rc = it.next();
-					
-					for ( RelatedContent x: content ){
+									
+				for ( RelatedContent c: content ){
 						
-						if ( x == rc ){
-							
-							it.remove();
-							
-							deleted = true;
-							
-							break;
-						}
+					if ( content_list.remove( c )){
+														
+						deleted = true;
 					}
 				}
 			}
@@ -944,8 +955,6 @@ RelatedContentUI
 		protected void
 		updateNumUnread()
 		{
-			boolean	changed = false;
-			
 			synchronized( RCMItem.this ){
 				
 				int	num = 0;
@@ -962,14 +971,24 @@ RelatedContentUI
 					
 					num_unread = num;
 					
-					changed = true;
+					final int f_num = num;
+										
+					async_dispatcher.dispatch(
+						new AERunnable()
+						{
+							public void
+							runSupport()
+							{
+								if ( async_dispatcher.getQueueSize() > 0 ){
+									
+									return;
+								}
+								
+								view.setNumUnread( f_num );
+							}
+						});
 				}
 			}
-			
-			if ( changed ){
-				
-				view.setNumUnread( num_unread );
-			}
 		}
 		
 		public void
diff --git a/com/aelitis/azureus/ui/swt/content/SBC_RCMView.java b/com/aelitis/azureus/ui/swt/content/SBC_RCMView.java
index 09d966a..051c5d3 100644
--- a/com/aelitis/azureus/ui/swt/content/SBC_RCMView.java
+++ b/com/aelitis/azureus/ui/swt/content/SBC_RCMView.java
@@ -23,18 +23,26 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.regex.Pattern;
 
 import org.eclipse.swt.SWT;
 
+import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.events.KeyEvent;
 import org.eclipse.swt.events.KeyListener;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.UrlUtils;
+
+import org.gudy.azureus2.core3.util.TorrentUtils;
 import org.gudy.azureus2.plugins.ui.UIManager;
 import org.gudy.azureus2.plugins.ui.tables.TableColumn;
 import org.gudy.azureus2.plugins.ui.tables.TableColumnCreationListener;
@@ -42,7 +50,7 @@ import org.gudy.azureus2.plugins.ui.tables.TableManager;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.*;
 
-import org.gudy.azureus2.ui.swt.views.table.TableViewSWTMenuFillListener;
+import org.gudy.azureus2.ui.swt.views.table.*;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
 
 import com.aelitis.azureus.core.AzureusCore;
@@ -55,8 +63,13 @@ import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
 import com.aelitis.azureus.ui.common.table.*;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
+import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfo;
+import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 import com.aelitis.azureus.ui.swt.content.columns.*;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectContainer;
+import com.aelitis.azureus.ui.swt.toolbar.ToolBarEnablerSelectedContent;
 import com.aelitis.azureus.ui.swt.views.skin.SkinView;
 import com.aelitis.azureus.ui.swt.views.skin.SkinViewManager;
 import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
@@ -66,7 +79,7 @@ import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
 public class 
 SBC_RCMView
 	extends SkinView
-	implements UIUpdatable, IconBarEnabler
+	implements UIUpdatable, IconBarEnabler, TableViewFilterCheck<RelatedContent>
 {
 	public static final String TABLE_RCM = "RCM";
 
@@ -84,11 +97,14 @@ SBC_RCMView
 		}
 	}
 	
-	private TableViewSWTImpl<RelatedContent> tv_related_content;
+	private TableViewSWT<RelatedContent> tv_related_content;
 
 	private SideBarEntrySWT 	sidebar_entry;
 	private Composite			table_parent;
+	private boolean				space_reserved;
+	
 	
+	private Text txtFilter;
 
 	public Object 
 	skinObjectInitialShow(
@@ -113,8 +129,35 @@ SBC_RCMView
 			sidebar_entry = sidebar.getCurrentEntry();
 			
 			sidebar_entry.setIconBarEnabler(this);
-		}
+
+			if ( !sidebar_entry.getId().equals( SideBar.SIDEBAR_SECTION_RELATED_CONTENT )){
 		
+				manager.reserveTemporarySpace();
+				
+				space_reserved = true;
+			}
+		}
+
+		SWTSkinObject soFilterArea = getSkinObject("filterarea");
+		if (soFilterArea != null) {
+			Composite parent = (Composite) soFilterArea.getControl();
+			FormData fd;
+			CLabel lblFilter = new CLabel(parent, SWT.CENTER);
+			Messages.setLanguageText(lblFilter, "MyTorrentsView.filter");
+			fd = Utils.getFilledFormData();
+			fd.right = null;
+			lblFilter.setLayoutData(fd);
+
+			txtFilter = new Text(parent, SWT.BORDER);
+			fd = new FormData();
+			fd.left = new FormAttachment(lblFilter, 10);
+			fd.top = new FormAttachment(lblFilter, 0, SWT.CENTER);
+			fd.right = new FormAttachment(100, -10);
+			txtFilter.setLayoutData(fd);
+			
+			parent.layout(true);
+		}
+
 		return null;
 	}
 
@@ -211,6 +254,34 @@ SBC_RCMView
 		
 		tableManager.registerColumn(
 				RelatedContent.class, 
+				ColumnRC_Created.COLUMN_ID,
+					new TableColumnCreationListener() {
+						public void tableColumnCreated(TableColumn column) {
+							new ColumnRC_Created(column);
+						}
+					});
+		tableManager.registerColumn(
+				RelatedContent.class, 
+				ColumnRC_Seeds.COLUMN_ID,
+					new TableColumnCreationListener() {
+						public void tableColumnCreated(TableColumn column) {
+							new ColumnRC_Seeds(column);
+						}
+					});
+
+		tableManager.registerColumn(
+				RelatedContent.class, 
+				ColumnRC_Peers.COLUMN_ID,
+					new TableColumnCreationListener() {
+						public void tableColumnCreated(TableColumn column) {
+							new ColumnRC_Peers(column);
+						}
+					});
+
+		
+		
+		tableManager.registerColumn(
+				RelatedContent.class, 
 				ColumnRC_LastSeen.COLUMN_ID,
 					new TableColumnCreationListener() {
 						public void tableColumnCreated(TableColumn column) {
@@ -277,6 +348,11 @@ SBC_RCMView
 			table_parent,
 		});
 
+		if ( space_reserved ){
+		
+			manager.releaseTemporarySpace();
+		}
+		
 		return( super.skinObjectDestroyed(skinObject, params));
 	}
 	
@@ -284,18 +360,24 @@ SBC_RCMView
 	initTable(
 		Composite control ) 
 	{
-
-		tv_related_content = 
-			new TableViewSWTImpl<RelatedContent>(
-					RelatedContent.class, 
-					TABLE_RCM,
-					TABLE_RCM, 
-					new TableColumnCore[0], 
-					ColumnRC_New.COLUMN_ID, 
-					SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL );
-		
+		tv_related_content = new TableViewSWTImpl<RelatedContent>(
+				RelatedContent.class, 
+				TABLE_RCM,
+				TABLE_RCM, 
+				new TableColumnCore[0], 
+				ColumnRC_New.COLUMN_ID, 
+				SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL );
+		if (txtFilter != null) {
+			tv_related_content.enableFilterCheck(txtFilter, this);
+		}
 		tv_related_content.setRowDefaultHeight(16);
-		tv_related_content.setHeaderVisible(true);
+		SWTSkinObject soSizeSlider = getSkinObject("table-size-slider");
+		if (soSizeSlider instanceof SWTSkinObjectContainer) {
+			SWTSkinObjectContainer so = (SWTSkinObjectContainer) soSizeSlider;
+			if (!tv_related_content.enableSizeSlider(so.getComposite(), 16, 100)) {
+				so.setVisible(false);
+			}
+		}
 		
 		table_parent = new Composite(control, SWT.NONE);
 		table_parent.setLayoutData(Utils.getFilledFormData());
@@ -305,7 +387,34 @@ SBC_RCMView
 
 		tv_related_content.addSelectionListener(new TableSelectionListener() {
 
-			public void selected(TableRowCore[] row) {
+			public void 
+			selected(
+				TableRowCore[] rows) 
+			{				
+				ArrayList<ISelectedContent>	valid = new ArrayList<ISelectedContent>();
+				
+				for (int i=0;i<rows.length;i++){
+					
+					final RelatedContent rc = (RelatedContent)rows[i].getDataSource();
+					
+					if ( rc.getHash() != null ){
+
+						valid.add(
+							new ToolBarEnablerSelectedContent( SBC_RCMView.this )
+							{
+								public DownloadUrlInfo 
+								getDownloadInfo() 
+								{
+									return(	new DownloadUrlInfo( TorrentUtils.getMagnetURI( rc.getHash())));
+								}
+							});
+					}
+				}
+				
+				ISelectedContent[] sels = valid.toArray( new ISelectedContent[valid.size()] );
+				
+				SelectedContentManager.changeCurrentlySelectedContent( "IconBarEnabler", sels, null );
+				
 				UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
 				if (uiFunctions != null) {
 					uiFunctions.refreshIconBar();
@@ -341,140 +450,123 @@ SBC_RCMView
 			{
 				private Set<RelatedContent>	content_set = new HashSet<RelatedContent>();
 				
-				private boolean destroyed;
+				private int liveness_marker;
 				
-				private RelatedContentManagerListener rcm_listener = 
-					new RelatedContentManagerListener()
-					{
-						public void
-						contentFound(
-							RelatedContent[]	content )
-						{							
-						}
-
-						public void
-						contentChanged(
-							RelatedContent[]	content )
+				private RelatedContentManagerListener current_rcm_listener;
+				
+				
+				public void 
+				tableViewInitialized() 
+				{
+					final int current_liveness_marker = ++liveness_marker;
+					
+					current_rcm_listener = 
+						new RelatedContentManagerListener()
 						{
-							boolean	hit = false;
+							public void
+							contentFound(
+								RelatedContent[]	content )
+							{							
+							}
 
-							synchronized( content_set ){
-								
-								if ( destroyed ){
+							public void
+							contentChanged(
+								RelatedContent[]	content )
+							{
+								final java.util.List<RelatedContent> hits = new ArrayList<RelatedContent>( content.length );
+
+								synchronized( content_set ){
 									
-									return;
-								}							
-							
-								for ( RelatedContent c: content ){
+									if ( liveness_marker != current_liveness_marker ){
+										
+										return;
+									}							
+								
+									for ( RelatedContent c: content ){
 
-									if ( content_set.contains( c )){
+										if ( content_set.contains( c )){
+									
+											hits.add( c );
+										}
+									}
+								}
 								
-										hit = true;
+								if ( hits.size() > 0 ){
+									
+									for (RelatedContent rc : hits) {
+										TableRowCore row = tv_related_content.getRow(rc);
+										if (row != null) {
+											row.refresh(true);
+										}
 									}
 								}
 							}
 							
-							if ( hit ){
+							public void 
+							contentRemoved(
+								final RelatedContent[] content )
+							{
+								final java.util.List<RelatedContent> hits = new ArrayList<RelatedContent>( content.length );
 								
-								Utils.execSWTThread(
-										new Runnable()
-										{
-											public void
-											run()
+								synchronized( content_set ){
+									
+									if ( liveness_marker != current_liveness_marker ){
+										
+										return;
+									}
+								
+									for ( RelatedContent c: content ){
+									
+										if ( content_set.remove( c )){
+									
+											hits.add( c );
+										}
+									}
+								}
+								
+								if ( hits.size() > 0 ){
+									
+									Utils.execSWTThread(
+											new Runnable()
 											{
-												if ( tv_related_content != null && !tv_related_content.isDisposed()){
-													
-													tv_related_content.refreshTable( false );
+												public void
+												run()
+												{
+													if ( tv_related_content != null ){
+														
+														tv_related_content.removeDataSources( hits.toArray( new RelatedContent[ hits.size()] ));
+													}
 												}
-											}
-										});
+											});
+								}
 							}
-						}
-						
-						public void 
-						contentRemoved(
-							final RelatedContent[] content )
-						{
-							final java.util.List<RelatedContent> hits = new ArrayList<RelatedContent>( content.length );
 							
-							synchronized( content_set ){
-								
-								if ( destroyed ){
+							public void
+							contentChanged()
+							{
+								if ( tv_related_content != null ){
 									
-									return;
-								}
-							
-								for ( RelatedContent c: content ){
-								
-									if ( content_set.remove( c )){
-								
-										hits.add( c );
-									}
+									tv_related_content.refreshTable( false );
 								}
 							}
 							
-							if ( hits.size() > 0 ){
-								
-								Utils.execSWTThread(
-										new Runnable()
-										{
-											public void
-											run()
-											{
-												if ( tv_related_content != null && !tv_related_content.isDisposed()){
-													
-													tv_related_content.removeDataSources( hits.toArray( new RelatedContent[ hits.size()] ));
-												}
-											}
-										});
+							public void
+							contentReset()
+							{
+								if ( tv_related_content != null ){
+									
+									tv_related_content.removeAllTableRows();
+								}
 							}
-						}
-						
-						public void
-						contentChanged()
-						{
-							Utils.execSWTThread(
-									new Runnable()
-									{
-										public void
-										run()
-										{
-											if ( tv_related_content != null && !tv_related_content.isDisposed()){
-												
-												tv_related_content.refreshTable( false );
-											}
-										}
-									});
-						}
+						};
 						
-						public void
-						contentReset()
-						{
-							Utils.execSWTThread(
-									new Runnable()
-									{
-										public void
-										run()
-										{
-											if ( tv_related_content != null && !tv_related_content.isDisposed()){
-												
-												tv_related_content.removeAllTableRows();
-											}
-										}
-									});
-						}
-					};
+					manager.addListener( current_rcm_listener );
 				
-				public void 
-				tableViewInitialized() 
-				{
-					manager.addListener( rcm_listener );
-					
 					Object data_source = sidebar_entry.getDatasource();
 					
 					if ( data_source instanceof RelatedContentEnumerator ){
 						
-						final TableViewSWTImpl<RelatedContent> f_table = tv_related_content;
+						final TableViewSWT<RelatedContent> f_table = tv_related_content;
 						
 						((RelatedContentEnumerator)data_source).enumerate(
 							new RelatedContentEnumerator.RelatedContentEnumeratorListener()
@@ -487,7 +579,7 @@ SBC_RCMView
 									
 									synchronized( content_set ){
 										
-										if ( destroyed ){
+										if ( liveness_marker != current_liveness_marker ){
 											
 											return;
 										}
@@ -537,11 +629,11 @@ SBC_RCMView
 												public void
 												run()
 												{
-													if ( tv_related_content == f_table && !tv_related_content.isDisposed()){
+													if ( tv_related_content == f_table ){
 													
 														synchronized( content_set ){
 															
-															if ( destroyed ){
+															if ( liveness_marker != current_liveness_marker ){
 																
 																return;
 															}
@@ -560,11 +652,11 @@ SBC_RCMView
 				public void 
 				tableViewDestroyed() 
 				{
-					manager.removeListener( rcm_listener );
-
+					manager.removeListener( current_rcm_listener );
+					
 					synchronized( content_set ){
 						
-						destroyed = true;
+						liveness_marker++;
 					
 						content_set.clear();
 					}
@@ -583,6 +675,69 @@ SBC_RCMView
 
 					System.arraycopy(_related_content, 0, related_content, 0, related_content.length);
 
+					final MenuItem assoc_item = new MenuItem(menu, SWT.PUSH);
+
+					assoc_item.setText(MessageText.getString("rcm.contextmenu.lookupassoc"));
+
+					final ArrayList<RelatedContent> assoc_ok = new ArrayList<RelatedContent>();
+					
+					for ( RelatedContent c: related_content ){
+						
+						if ( c.getHash() != null ){
+							
+							assoc_ok.add( c );
+						}
+					}
+					
+					assoc_item.addSelectionListener(new SelectionAdapter() {
+						public void widgetSelected(SelectionEvent e ){
+							
+							int	 i = 0;
+							
+							RelatedContentUI ui = RelatedContentUI.getSingleton();
+							
+							for ( RelatedContent c: assoc_ok ){
+							
+								ui.addSearch( c.getHash(), c.getTitle());
+								
+								i++;
+								
+								if ( i > 8 ){
+									
+									break;
+								}
+							}
+						};
+					});
+					
+					if ( assoc_ok.size() == 0 ){
+						
+						assoc_item.setEnabled( false );
+					}
+
+					MenuItem item = new MenuItem(menu, SWT.PUSH);
+					item.setText("gis");
+					item.addSelectionListener(new SelectionAdapter() {
+						public void widgetSelected(SelectionEvent e) {
+							String s = related_content[0].getTitle();
+							s = s.replaceAll("[-_]", " ");
+							Utils.launch("http://images.google.com/images?q=" + UrlUtils.encode(s));
+						};
+					});
+
+					item = new MenuItem(menu, SWT.PUSH);
+					item.setText("g");
+					item.addSelectionListener(new SelectionAdapter() {
+						public void widgetSelected(SelectionEvent e) {
+							String s = related_content[0].getTitle();
+							s = s.replaceAll("[-_]", " ");
+							Utils.launch("http://google.com/search?q=" + UrlUtils.encode(s));
+						};
+					});
+
+					
+					new MenuItem(menu, SWT.SEPARATOR );
+
 					final MenuItem remove_item = new MenuItem(menu, SWT.PUSH);
 
 					remove_item.setText(MessageText.getString("azbuddy.ui.menu.remove"));
@@ -700,4 +855,27 @@ SBC_RCMView
 			tv_related_content.refreshTable( false );
 		}
 	}
+
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableViewFilterCheck#filterCheck(java.lang.Object, java.lang.String, boolean)
+	public boolean filterCheck(RelatedContent ds, String filter, boolean regex) {
+		if ( filter == null || filter.length() == 0 ){
+			
+			return( true );
+		}
+
+		try {
+			String name = ds.getTitle();
+			String s = regex ? filter : "\\Q" + filter.replaceAll("[|;]", "\\\\E|\\\\Q") + "\\E";
+  		Pattern pattern = Pattern.compile(s, Pattern.CASE_INSENSITIVE);
+  
+  		return pattern.matcher(name).find();
+		} catch (Exception e) {
+			return true;
+		}
+	}
+	
+	// @see org.gudy.azureus2.ui.swt.views.table.TableViewFilterCheck#filterSet(java.lang.String)
+	public void filterSet(String filter) {
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Created.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Created.java
new file mode 100644
index 0000000..56bacf4
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Created.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright (C) 2008 Vuze Inc., All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+package com.aelitis.azureus.ui.swt.content.columns;
+
+
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+
+import com.aelitis.azureus.core.content.RelatedContent;
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+
+
+/**
+ * @author Olivier Chalouhi
+ * @created Oct 7, 2008
+ *
+ */
+public class 
+ColumnRC_Created
+	implements TableCellRefreshListener
+{	
+	public static String COLUMN_ID = "rc_created";
+	
+	public 
+	ColumnRC_Created(
+		TableColumn column )
+	{
+		column.initialize(TableColumn.ALIGN_TRAIL, TableColumn.POSITION_LAST, 90 );
+		column.addListeners(this);
+		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+
+		if ( column instanceof TableColumnCore ){
+			((TableColumnCore)column).setUseCoreDataSource( true );
+		}
+	}
+
+	public void refresh(TableCell cell) {
+		RelatedContent rc = (RelatedContent) cell.getDataSource();
+		if (rc == null) {
+			return;
+		}
+
+		long date = rc.getPublishDate();
+
+		if ( cell.setSortValue( date )){
+
+			cell.setText( date <= 0?"--":DisplayFormatters.formatCustomDateOnly( date ));
+		}
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Hash.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Hash.java
index fbaaa49..eaac9f2 100644
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Hash.java
+++ b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Hash.java
@@ -25,6 +25,7 @@ import org.eclipse.swt.SWT;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.ByteFormatter;
 import org.gudy.azureus2.plugins.ui.tables.*;
+import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
 import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
 
 /**
@@ -79,7 +80,6 @@ public class ColumnRC_Hash
 		cell.setText(ByteFormatter.encodeString(hash));
 	}
 	
-	/*
 	public void cellMouseTrigger(final TableCellMouseEvent event) {
 		if (event.eventType == TableRowMouseEvent.EVENT_MOUSEDOWN
 				&& event.button == 1) {
@@ -95,5 +95,4 @@ public class ColumnRC_Hash
 			}
 		}
 	}
-	*/
 }
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_LastSeen.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_LastSeen.java
index 8d472da..e6db8ad 100644
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_LastSeen.java
+++ b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_LastSeen.java
@@ -39,7 +39,7 @@ public class ColumnRC_LastSeen
 	 * @param sTableID
 	 */
 	public ColumnRC_LastSeen(TableColumn column) {
-		column.initialize(TableColumn.ALIGN_TRAIL, TableColumn.POSITION_LAST, 90 );
+		column.initialize(TableColumn.ALIGN_TRAIL, TableColumn.POSITION_INVISIBLE, 90 );
 		column.addListeners(this);
 		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
 		column.setType(TableColumn.TYPE_TEXT_ONLY);
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Level.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Level.java
index 57ce15b..922f31e 100644
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Level.java
+++ b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Level.java
@@ -38,7 +38,7 @@ public class ColumnRC_Level
 	 * @param sTableID
 	 */
 	public ColumnRC_Level(TableColumn column) {
-		column.initialize(TableColumn.ALIGN_CENTER, TableColumn.POSITION_LAST, 40 );
+		column.initialize(TableColumn.ALIGN_CENTER, TableColumn.POSITION_INVISIBLE, 40 );
 		column.addListeners(this);
 		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
 		column.setType(TableColumn.TYPE_TEXT_ONLY);
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_New.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_New.java
index 542d15e..db456ba 100644
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_New.java
+++ b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_New.java
@@ -97,13 +97,11 @@ public class ColumnRC_New
 			
 			boolean unread = entry.isUnread();
 			
-			int sortVal = unread ? 1 : 0;
+			long sortVal = ((unread ? 2 : 1) << 62) + entry.getLastSeenSecs();
 	
 			if (!cell.setSortValue(sortVal) && cell.isValid()) {
 				return;
 			}
-	
-			cell.invalidate();
 		}
 	}
 
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Peers.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Peers.java
new file mode 100644
index 0000000..9f043df
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Peers.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (C) 2008 Vuze Inc., All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+package com.aelitis.azureus.ui.swt.content.columns;
+
+
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+
+import com.aelitis.azureus.core.content.RelatedContent;
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+
+
+/**
+ * @author Olivier Chalouhi
+ * @created Oct 7, 2008
+ *
+ */
+public class 
+ColumnRC_Peers
+	implements TableCellRefreshListener
+{	
+	public static String COLUMN_ID = "rc_peers";
+	
+	public 
+	ColumnRC_Peers(
+		TableColumn column )
+	{
+		column.initialize(TableColumn.ALIGN_CENTER, TableColumn.POSITION_LAST, 60 );
+		column.addListeners(this);
+		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+
+		if ( column instanceof TableColumnCore ){
+			((TableColumnCore)column).setUseCoreDataSource( true );
+		}
+	}
+
+	public void refresh(TableCell cell) {
+		RelatedContent rc = (RelatedContent) cell.getDataSource();
+		if (rc == null) {
+			return;
+		}
+
+		long peers = rc.getLeechers();
+
+		if ( cell.setSortValue( peers )){
+
+			cell.setText( peers < 0?"--":String.valueOf(peers));
+		}
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Seeds.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Seeds.java
new file mode 100644
index 0000000..290a1c9
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Seeds.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (C) 2008 Vuze Inc., All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+package com.aelitis.azureus.ui.swt.content.columns;
+
+
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+
+import com.aelitis.azureus.core.content.RelatedContent;
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+
+
+/**
+ * @author Olivier Chalouhi
+ * @created Oct 7, 2008
+ *
+ */
+public class 
+ColumnRC_Seeds
+	implements TableCellRefreshListener
+{	
+	public static String COLUMN_ID = "rc_seeds";
+	
+	public 
+	ColumnRC_Seeds(
+		TableColumn column )
+	{
+		column.initialize(TableColumn.ALIGN_CENTER, TableColumn.POSITION_LAST, 60 );
+		column.addListeners(this);
+		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+
+		if ( column instanceof TableColumnCore ){
+			((TableColumnCore)column).setUseCoreDataSource( true );
+		}
+	}
+
+	public void refresh(TableCell cell) {
+		RelatedContent rc = (RelatedContent) cell.getDataSource();
+		if (rc == null) {
+			return;
+		}
+
+		long seeds = rc.getSeeds();
+
+		if ( cell.setSortValue( seeds )){
+
+			cell.setText( seeds < 0?"--":String.valueOf(seeds));
+		}
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Title.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Title.java
index 3f16ce0..d0f2521 100644
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Title.java
+++ b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Title.java
@@ -20,12 +20,12 @@ package com.aelitis.azureus.ui.swt.content.columns;
 
 import com.aelitis.azureus.core.content.RelatedContent;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
-import com.aelitis.azureus.ui.swt.shells.main.MainWindow;
+//import com.aelitis.azureus.ui.swt.shells.main.MainWindow;
 
-import org.eclipse.swt.SWT;
-import org.gudy.azureus2.core3.internat.MessageText;
+//import org.eclipse.swt.SWT;
+//import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.plugins.ui.tables.*;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
+//import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
 
 /**
  * @author TuxPaper
@@ -33,7 +33,7 @@ import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
  *
  */
 public class ColumnRC_Title
-	implements TableCellRefreshListener, TableCellMouseListener, TableCellAddedListener
+	implements TableCellRefreshListener //, TableCellMouseListener, TableCellAddedListener
 {
 	public static final String COLUMN_ID = "rc_title";
 
@@ -68,6 +68,7 @@ public class ColumnRC_Title
 		cell.setText(text);
 	}
 	
+	/*
 	public void cellAdded(TableCell cell) {
 		
 		RelatedContent rc = (RelatedContent) cell.getDataSource();
@@ -95,4 +96,5 @@ public class ColumnRC_Title
 			}
 		}
 	}
+	*/
 }
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Tracker.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Tracker.java
index 8b26027..7408ba4 100644
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Tracker.java
+++ b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Tracker.java
@@ -24,7 +24,7 @@ import com.aelitis.azureus.ui.common.table.TableColumnCore;
 import org.eclipse.swt.SWT;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.plugins.ui.tables.*;
-// import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
 
 /**
@@ -77,7 +77,6 @@ public class ColumnRC_Tracker
 		}
 	}
 	
-	/*
 	public void cellMouseTrigger(final TableCellMouseEvent event) {
 		if (event.eventType == TableRowMouseEvent.EVENT_MOUSEDOWN
 				&& event.button == 1) {
@@ -93,7 +92,6 @@ public class ColumnRC_Tracker
 			}
 		}
 	}
-	*/
 	
 	private boolean
 	validTracker(
diff --git a/com/aelitis/azureus/ui/swt/devices/DeviceManagerUI.java b/com/aelitis/azureus/ui/swt/devices/DeviceManagerUI.java
index 5d3b310..477c0bf 100644
--- a/com/aelitis/azureus/ui/swt/devices/DeviceManagerUI.java
+++ b/com/aelitis/azureus/ui/swt/devices/DeviceManagerUI.java
@@ -26,16 +26,13 @@ package com.aelitis.azureus.ui.swt.devices;
 import java.io.File;
 import java.net.InetAddress;
 import java.util.*;
+import java.util.List;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.DirectoryDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
@@ -45,20 +42,17 @@ import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.installer.PluginInstaller;
 import org.gudy.azureus2.plugins.installer.StandardPlugin;
-import org.gudy.azureus2.plugins.ui.UIInstance;
-import org.gudy.azureus2.plugins.ui.UIManager;
-import org.gudy.azureus2.plugins.ui.UIManagerListener;
+import org.gudy.azureus2.plugins.ui.*;
 import org.gudy.azureus2.plugins.ui.config.*;
 import org.gudy.azureus2.plugins.ui.menus.*;
+import org.gudy.azureus2.plugins.ui.menus.MenuItem;
 import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
 import org.gudy.azureus2.plugins.ui.sidebar.*;
 import org.gudy.azureus2.plugins.ui.tables.TableContextMenuItem;
 import org.gudy.azureus2.plugins.ui.tables.TableManager;
 import org.gudy.azureus2.plugins.ui.tables.TableRow;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
-import org.gudy.azureus2.ui.swt.PropertiesWindow;
-import org.gudy.azureus2.ui.swt.UIExitUtilsSWT;
-import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.*;
 import org.gudy.azureus2.ui.swt.plugins.UISWTInputReceiver;
 import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
@@ -76,6 +70,7 @@ import com.aelitis.azureus.core.download.DiskManagerFileInfoFile;
 import com.aelitis.azureus.core.messenger.config.PlatformDevicesMessenger;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
 import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
@@ -111,7 +106,8 @@ DeviceManagerUI
 	private static final String INFO_IMAGE_ID		= "image.sidebar.vitality.info";
 	private static final String ALERT_IMAGE_ID		= "image.sidebar.vitality.alert";
 
-	private static final boolean	SHOW_VITALITY = false;
+	private static final boolean	SHOW_RENDERER_VITALITY 	= false;
+	private static final boolean	SHOW_OD_VITALITY 		= true;
 	
 	private static final String[] to_copy_indicator_colors = { "#000000", "#000000", "#168866", "#1c5620" };
 	
@@ -152,6 +148,9 @@ DeviceManagerUI
 	
 	private MenuItemFillListener will_browse_listener;
 	
+	private boolean	offline_menus_setup;
+	
+	
 	static {
 		try {
   		if (Constants.isOSX) {
@@ -249,35 +248,27 @@ DeviceManagerUI
   						
   						return( true );
   					}
-					
-  					boolean allowQuit =
-  						Utils.execSWTThreadWithBool(
-  							"quitTranscoding",
-  							new AERunnableBoolean() {
-  								public boolean runSupport() {
-  									String title = MessageText.getString("device.quit.transcoding.title");
-  									String text = MessageText.getString(
-  											"device.quit.transcoding.text",
-  											new String[] {
-  												job.getName(),
-  												job.getTarget().getDevice().getName(),
-  												String.valueOf( job.getPercentComplete())
-  											});
-  
-  									MessageBoxShell mb = new MessageBoxShell(
-  											Utils.findAnyShell(),
-  											title,
-  											text,
-  											new String[] {
-  												MessageText.getString("UpdateWindow.quit"),
-  												MessageText.getString("Content.alert.notuploaded.button.abort")
-  											}, 1, null, null, false, 0);
-  
-  									return mb.open() == 0;
-  								}
-  							}, 0);
-  					
-  					return( allowQuit );
+
+						String title = MessageText.getString("device.quit.transcoding.title");
+						String text = MessageText.getString(
+								"device.quit.transcoding.text",
+								new String[] {
+									job.getName(),
+									job.getTarget().getDevice().getName(),
+									String.valueOf( job.getPercentComplete())
+								});
+
+						MessageBoxShell mb = new MessageBoxShell(
+								title,
+								text,
+								new String[] {
+									MessageText.getString("UpdateWindow.quit"),
+									MessageText.getString("Content.alert.notuploaded.button.abort")
+								}, 1);
+						mb.open(null);
+						mb.waitUntilClosed();
+						return mb.getResult() == 0;
+
 					} catch (Exception e) {
 						Debug.out(e);
 						return true;
@@ -447,20 +438,20 @@ DeviceManagerUI
 				device_manager.getAutoSearch());
 		
 		as.addListener(
-				new ParameterListener()
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param) 
 				{
-					public void 
-					parameterChanged(
-						Parameter param) 
-					{
-						device_manager.setAutoSearch( as.getValue());
+					device_manager.setAutoSearch( as.getValue());
+					
+					if ( device_manager.getAutoSearch()){
 						
-						if ( device_manager.getAutoSearch()){
-							
-							search();
-						}
+						search();
 					}
-				});
+				}
+			});
 		
 		final BooleanParameter qosParam = configModel.addBooleanParameter2(
 				PlatformDevicesMessenger.CFG_SEND_QOS, "devices.turnon.qos", false);
@@ -477,25 +468,6 @@ DeviceManagerUI
 				}
 			});
 
-			// max xcode
-		
-		final IntParameter max_xcode = 
-			configModel.addIntParameter2( 
-				"device.config.xcode.maxbps", "device.config.xcode.maxbps",
-				(int)(device_manager.getTranscodeManager().getQueue().getMaxBytesPerSecond()/1024), 
-				0, Integer.MAX_VALUE );
-		
-		max_xcode.addListener(
-			new ParameterListener()
-			{
-				public void 
-				parameterChanged(
-					Parameter param) 
-				{
-					device_manager.getTranscodeManager().getQueue().setMaxBytesPerSecond( max_xcode.getValue()*1024 );
-				}
-			});
-
 			// config - simple view
 		
 		final BooleanParameter config_simple_view = 
@@ -504,15 +476,15 @@ DeviceManagerUI
 				side_bar_view_type == SBV_SIMPLE );
 		
 		config_simple_view.addListener(
-				new ParameterListener()
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param) 
 				{
-					public void 
-					parameterChanged(
-						Parameter param) 
-					{
-						COConfigurationManager.setParameter( CONFIG_VIEW_TYPE, config_simple_view.getValue()?SBV_SIMPLE:SBV_FULL );
-					}
-				});	
+					COConfigurationManager.setParameter( CONFIG_VIEW_TYPE, config_simple_view.getValue()?SBV_SIMPLE:SBV_FULL );
+				}
+			});	
 		
 		COConfigurationManager.addParameterListener(
 			CONFIG_VIEW_TYPE,
@@ -532,6 +504,8 @@ DeviceManagerUI
 				"!" + CONFIG_VIEW_HIDE_REND_GENERIC + "!", "devices.sidebar.hide.rend.generic",
 				side_bar_hide_rend_gen );
 		
+		// transcoding
+		
 			// default dir
 		
 		String def = device_manager.getDefaultWorkingDirectory().getAbsolutePath();
@@ -551,81 +525,28 @@ DeviceManagerUI
 				}
 			});
 		
-			// rss
-		
-		final BooleanParameter rss_enable = 
-			configModel.addBooleanParameter2( 
-				"device.rss.enable", "device.rss.enable",
-				device_manager.isRSSPublishEnabled());
-		
-		rss_enable.addListener(
-				new ParameterListener()
-				{
-					public void 
-					parameterChanged(
-						Parameter param) 
-					{
-						device_manager.setRSSPublishEnabled( rss_enable.getValue());
-					}
-				});
-		
+			// max xcode
 		
-		final IntParameter rss_port = 
+		final IntParameter max_xcode = 
 			configModel.addIntParameter2( 
-				"device.rss.port", "device.rss.port",
-				device_manager.getRSSPort());
-		
-		final BooleanParameter rss_localonly = 
-			configModel.addBooleanParameter2( 
-				"device.rss.localonly", "device.rss.localonly",
-				device_manager.isRSSLocalOnly());
-		
-		rss_localonly.addListener(
-				new ParameterListener()
-				{
-					public void 
-					parameterChanged(
-						Parameter param) 
-					{
-						device_manager.setRSSLocalOnly( rss_localonly.getValue());
-					}
-				});
-		
-		final HyperlinkParameter rss_view = 
-			configModel.addHyperlinkParameter2(
-				"device.rss.view", getRSSLink( rss_port.getValue()));
-		
-		rss_port.addListener(
-				new ParameterListener()
-				{
-					public void 
-					parameterChanged(
-						Parameter param) 
-					{
-						int port =  rss_port.getValue();
-						
-						device_manager.setRSSPort( port );
-						
-						rss_view.setHyperlink( getRSSLink( port ));
-					}
-				});
-
-
-		
-		rss_enable.addEnabledOnSelection( rss_localonly );
-		rss_enable.addEnabledOnSelection( rss_port );
-		rss_enable.addEnabledOnSelection( rss_view );
+				"device.config.xcode.maxbps", "device.config.xcode.maxbps",
+				(int)(device_manager.getTranscodeManager().getQueue().getMaxBytesPerSecond()/1024), 
+				0, Integer.MAX_VALUE );
 		
-		configModel.createGroup(
-			"device.rss.group",
-			new Parameter[]
+		max_xcode.addListener(
+			new ParameterListener()
 			{
-					rss_enable, rss_port, rss_view, rss_localonly,
+				public void 
+				parameterChanged(
+					Parameter param) 
+				{
+					device_manager.getTranscodeManager().getQueue().setMaxBytesPerSecond( max_xcode.getValue()*1024 );
+				}
 			});
-		
+
 			// itunes
 		
-		final ActionParameter btnITunes = configModel.addActionParameter2(null, "devices.button.installitunes");
+		final ActionParameter btnITunes = configModel.addActionParameter2("devices.button.installitunes", "UpdateWindow.columns.install");
 		btnITunes.setEnabled(false);
 		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(AzureusCore core) {
@@ -653,10 +574,136 @@ DeviceManagerUI
 				});
 			}
 		});
+		
+		configModel.createGroup(
+			"device.xcode.group",
+			new Parameter[]
+			{
+					def_work_dir, max_xcode, btnITunes
+			});
+		
+			// rss
+		
+		final BooleanParameter rss_enable = 
+			configModel.addBooleanParameter2( 
+				"device.rss.enable", "device.rss.enable",
+				device_manager.isRSSPublishEnabled());
+		
+		rss_enable.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param) 
+				{
+					device_manager.setRSSPublishEnabled( rss_enable.getValue());
+				}
+			});
+				
+		HyperlinkParameter rss_view = 
+			configModel.addHyperlinkParameter2(
+				"device.rss.view", device_manager.getRSSLink());
+		
+		rss_enable.addEnabledOnSelection( rss_view );
+		
+		configModel.createGroup(
+			"device.rss.group",
+			new Parameter[]
+			{
+					rss_enable, rss_view,
+			});
 
+			// offline downloaders
+		
+				// enable
+		
+		final DeviceOfflineDownloaderManager dodm = device_manager.getOfflineDownlaoderManager();
+		
+		final BooleanParameter od_enable = 
+			configModel.addBooleanParameter2( 
+				"device.od.enable", "device.od.enable",
+				dodm.isOfflineDownloadingEnabled());
+		
+		od_enable.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param) 
+				{
+					dodm.setOfflineDownloadingEnabled( od_enable.getValue());
+					
+					rebuildSideBar();
+				}
+			});
+		
+				// auto manage
+		
+		final BooleanParameter od_auto_enable = 
+			configModel.addBooleanParameter2( 
+				"device.odauto.enable", "device.odauto.enable",
+				dodm.getOfflineDownloadingIsAuto());
+		
+		od_auto_enable.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param) 
+				{
+					dodm.setOfflineDownloadingIsAuto( od_auto_enable.getValue());
+				}
+			});
+		
+				// private torrents
+		
+		final BooleanParameter od_pt_enable = 
+			configModel.addBooleanParameter2( 
+				"device.odpt.enable", "device.odpt.enable",
+				dodm.getOfflineDownloadingIncludePrivate());
+		
+		od_pt_enable.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param) 
+				{
+					dodm.setOfflineDownloadingIncludePrivate( od_pt_enable.getValue());
+				}
+			});
+		
+		od_auto_enable.addEnabledOnSelection( od_pt_enable );
+		
+		configModel.createGroup(
+			"device.od.group",
+			new Parameter[]
+			{
+				od_enable, od_auto_enable, od_pt_enable,
+			});
+		
+		final BooleanParameter tivo_enable = 
+			configModel.addBooleanParameter2( 
+				"device.tivo.enable", "device.tivo.enable", false );
+		
+		tivo_enable.setValue(device_manager.isTiVoEnabled());
+		
+		tivo_enable.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param) 
+				{
+					device_manager.setTiVoEnabled( tivo_enable.getValue());
+					
+					rebuildSideBar();
+				}
+			});
+		
 		addAllDevices();
 	
-		setupMenus();
+		setupTranscodeMenus();
 	}
 	
 	protected String
@@ -717,7 +764,7 @@ DeviceManagerUI
 							
 							SideBarEntry info = (SideBarEntry) target;
 							
-							Device device = (Device)info.getDatasource();
+							final Device device = (Device)info.getDatasource();
 							
 							UISWTInputReceiver entry = (UISWTInputReceiver)swt_ui.getInputReceiver();
 							
@@ -727,21 +774,24 @@ DeviceManagerUI
 							
 							entry.allowEmptyInput( false );
 							
-							entry.setTitle("MyTorrentsView.menu.rename");
-							
-							entry.prompt();
-							
-							if (!entry.hasSubmittedInput()){
-								
-								return;
-							}
-							
-							String input = entry.getSubmittedInput().trim();
-							
-							if ( input.length() > 0 ){
-							
-								device.setName( input );
-							}
+							entry.setLocalisedTitle(MessageText.getString("label.rename",
+									new String[] {
+								device.getName()
+							}));
+	
+							entry.prompt(new UIInputReceiverListener() {
+								public void UIInputReceiverClosed(UIInputReceiver entry) {
+									if (!entry.hasSubmittedInput()) {
+										return;
+									}
+									String input = entry.getSubmittedInput().trim();
+									
+									if ( input.length() > 0 ){
+										
+										device.setName( input );
+									}
+								}
+							});		
 						}
 					}
 				};
@@ -951,8 +1001,8 @@ DeviceManagerUI
 						
 						menu.setEnabled( enabled );
 					}
-				};
 			
+				};
 		side_bar.addListener(
 			new SideBarListener()
 			{
@@ -991,7 +1041,6 @@ DeviceManagerUI
 									{
 										MessageBoxShell mb = 
 											new MessageBoxShell(
-												Utils.findAnyShell(),
 												MessageText.getString("message.confirm.delete.title"),
 												MessageText.getString("message.confirm.delete.text",
 														new String[] {
@@ -1003,10 +1052,13 @@ DeviceManagerUI
 												},
 												1 );
 										
-										int result = mb.open();
-										if (result == 0) {
-											device.remove();
-										}
+										mb.open(new UserPrompterResultListener() {
+											public void prompterClosed(int result) {
+												if (result == 0) {
+													device.remove();
+												}
+											}
+										});
 									}
 								})};
 										
@@ -1030,22 +1082,7 @@ DeviceManagerUI
 					
 					side_bar_hide_rend_gen = COConfigurationManager.getBooleanParameter( CONFIG_VIEW_HIDE_REND_GENERIC, true );
 
-					if ( sidebar_built ){
-						
-						Utils.execSWTThread(
-								new Runnable()
-								{
-									public void
-									run()
-									{
-										removeAllDevices();
-										
-										buildSideBar( true );
-										
-										addAllDevices();
-									}
-								});
-					}
+					rebuildSideBar();
 				}
 			});
 	}
@@ -1076,6 +1113,27 @@ DeviceManagerUI
 	}
 	
 	protected void
+	rebuildSideBar()
+	{
+		if ( sidebar_built ){
+			
+			Utils.execSWTThread(
+					new Runnable()
+					{
+						public void
+						run()
+						{
+							removeAllDevices();
+							
+							buildSideBar( true );
+							
+							addAllDevices();
+						}
+					});
+		}
+	}
+	
+	protected void
 	buildSideBar(
 		boolean			rebuild )	
 	{		
@@ -1183,9 +1241,20 @@ DeviceManagerUI
 										
 										if ( device instanceof DeviceMediaRenderer ){
 									
-											DeviceMediaRenderer	renderer = (DeviceMediaRenderer)device;
+											if ( SHOW_RENDERER_VITALITY ){
+												
+												DeviceMediaRenderer	renderer = (DeviceMediaRenderer)device;
+												
+												last_indicator += renderer.getCopyToDevicePending() + renderer.getCopyToFolderPending();
+											}
+										}else if ( device instanceof DeviceOfflineDownloader ){
 											
-											last_indicator += renderer.getCopyToDevicePending() + renderer.getCopyToFolderPending();
+											if ( SHOW_OD_VITALITY ){
+												
+												DeviceOfflineDownloader	dod = (DeviceOfflineDownloader)device;
+												
+												last_indicator += dod.getTransferingCount();
+											}
 										}
 									}
 									
@@ -1210,11 +1279,8 @@ DeviceManagerUI
 									}
 									
 									if ( last_indicator > 0 ){
-											
-										if ( SHOW_VITALITY ){
-											
-											return( String.valueOf( last_indicator ));
-										}
+																						
+										return( String.valueOf( last_indicator ));
 									}
 								}else{
 									
@@ -1224,6 +1290,7 @@ DeviceManagerUI
 								}
 							}else if ( propertyID == TITLE_INDICATOR_COLOR ){
 									
+								/*
 								if ( last_indicator > 0 ){
 									
 									if ( SHOW_VITALITY ){
@@ -1231,6 +1298,7 @@ DeviceManagerUI
 										return( to_copy_indicator_colors );
 									}
 								}
+								*/
 							}
 
 							return null;
@@ -1382,7 +1450,7 @@ DeviceManagerUI
 	
 					// routers
 				
-				categoryView routers_category			= addDeviceCategory( Device.DT_INTERNET_GATEWAY, "device.router.view.title", 			"image.sidebar.device.router" );
+				categoryView routers_category			= addDeviceCategory( Device.DT_INTERNET_GATEWAY, "device.router.view.title", "image.sidebar.device.router" );
 				
 				categories.add( routers_category );
 				
@@ -1409,6 +1477,15 @@ DeviceManagerUI
 							}
 						});
 				
+					// offline downloaders
+				
+				if ( device_manager.getOfflineDownlaoderManager().isOfflineDownloadingEnabled()){
+					
+					categoryView od_category	= addDeviceCategory( Device.DT_OFFLINE_DOWNLOADER, "device.offlinedownloader.view.title", "image.sidebar.device.offlinedownloader" );
+					
+					categories.add( od_category );
+				}
+				
 					// internet
 				
 				categoryView internet_category	= addDeviceCategory( Device.DT_INTERNET, "MainWindow.about.section.internet", "image.sidebar.device.internet" );
@@ -1467,7 +1544,7 @@ DeviceManagerUI
 	}
 
 	private void 
-	setupMenus()
+	setupTranscodeMenus()
 	{					
 			// top level menus
 				
@@ -1637,6 +1714,134 @@ DeviceManagerUI
 		}
 	}
 	
+	private void 
+	setupOfflineDownloadingMenus()
+	{					
+		final String[] tables = {
+				TableManager.TABLE_MYTORRENTS_INCOMPLETE,
+				TableManager.TABLE_MYTORRENTS_INCOMPLETE_BIG,
+				TableManager.TABLE_MYTORRENTS_ALL_BIG,
+			};
+		
+		TableManager table_manager = plugin_interface.getUIManager().getTableManager();
+		
+		final DeviceOfflineDownloaderManager dodm = device_manager.getOfflineDownlaoderManager();
+		
+		MenuItemFillListener	menu_fill_listener = 
+			new MenuItemFillListener()
+			{
+				public void
+				menuWillBeShown(
+					MenuItem	menu,
+					Object		_target )
+				{
+					menu.removeAllChildItems();
+
+					if ( dodm.getOfflineDownloadingIsAuto()){
+						
+						menu.setEnabled( true );
+						
+						TableContextMenuItem auto_item =
+							plugin_interface.getUIManager().getTableManager().addContextMenuItem(
+								(TableContextMenuItem)menu,
+								"devices.contextmenu.od.auto");
+						
+						auto_item.setEnabled( false );
+
+						return;
+					}
+			
+					final TableRow[]	target;
+					
+					if ( _target instanceof TableRow ){
+						
+						target = new TableRow[]{ (TableRow)_target };
+						
+					}else{
+						
+						target = (TableRow[])_target;
+					}
+										
+					boolean	all_non_manual	= true;
+					boolean all_manual		= true;
+					
+					final List<Download> downloads = new ArrayList<Download>();
+					
+					for ( TableRow row: target ){
+						
+						Object obj = row.getDataSource();
+					
+						if ( obj instanceof Download ){
+						
+							Download download = (Download)obj;
+
+							downloads.add( download );
+							
+							if ( dodm.isManualDownload( download )){
+								
+								all_non_manual = false;
+								
+							}else{
+								
+								all_manual = false;
+							}
+						}
+					}
+					
+					boolean	enabled = downloads.size() > 0;
+
+					menu.setEnabled( enabled );
+										
+					if ( enabled ){
+						
+						TableContextMenuItem manual_item =
+							plugin_interface.getUIManager().getTableManager().addContextMenuItem(
+								(TableContextMenuItem)menu,
+								"devices.contextmenu.od.enable" + (all_manual?"d":""));
+						
+						final boolean f_all_manual = all_manual;
+						
+						manual_item.setData( new Boolean( f_all_manual ));
+						
+						manual_item.setStyle( MenuItem.STYLE_CHECK );
+						
+						manual_item.addListener(
+							new MenuItemListener()
+							{
+								public void
+								selected(
+									MenuItem			menu,
+									Object 				target )
+								{
+									Download[] d = downloads.toArray( new Download[ downloads.size()]);
+									
+									if ( f_all_manual ){
+										
+										dodm.removeManualDownloads( d );
+										
+									}else{
+										
+										dodm.addManualDownloads( d );
+									}
+								}
+							});
+					}
+				}
+			};
+		
+		// TUX TODO: make a table_manager.addContentMenuItem(Class forDataSourceType, String resourceKey)
+		//           instead of forcing a loop like this
+			
+		for( String table: tables ){
+				
+			TableContextMenuItem menu = table_manager.addContextMenuItem(table, "devices.contextmenu.od" );
+			
+			menu.setStyle(TableContextMenuItem.STYLE_MENU);
+		
+			menu.addFillListener( menu_fill_listener );				
+		}
+	}
+	
 	protected void
 	search()
 	{
@@ -1663,6 +1868,11 @@ DeviceManagerUI
 	{
 		int	type = device.getType();
 		
+		if ( !device_manager.getOfflineDownlaoderManager().isOfflineDownloadingEnabled() && type == Device.DT_OFFLINE_DOWNLOADER ){
+			
+			return;
+		}
+		
 		String parent_key = null;
 		
 		if ( side_bar_view_type == SBV_FULL ){
@@ -1678,7 +1888,7 @@ DeviceManagerUI
 			}
 		}else{
 			
-			if ( type != Device.DT_MEDIA_RENDERER ){
+			if ( type != Device.DT_MEDIA_RENDERER && type != Device.DT_OFFLINE_DOWNLOADER ){
 				
 				return;
 			}
@@ -1711,15 +1921,38 @@ DeviceManagerUI
 			
 			return;
 		}
-		
+				
 		final String parent = parent_key;
 		
 		synchronized( this ){
-			
+
 			final deviceItem existing_di = (deviceItem)device.getTransientProperty( DEVICE_IVIEW_KEY );
 			
 			if (  existing_di == null ){
 	
+				if ( type == Device.DT_OFFLINE_DOWNLOADER ){
+
+					if ( !offline_menus_setup ){
+					
+						offline_menus_setup = true;
+					
+						setupOfflineDownloadingMenus();
+					}
+					
+					DeviceOfflineDownloader	dod = (DeviceOfflineDownloader)device;
+					
+					if ( !dod.hasShownFTUX()){
+						
+						try{
+							new DevicesODFTUX( dod );
+														
+						}catch( Throwable e ){
+							
+							Debug.out( "Failed to show offline downloader FTUX", e );
+						}
+					}
+				}
+				
 				if ( !device.isHidden()){
 					
 					final deviceItem new_di = new deviceItem();
@@ -1747,7 +1980,9 @@ DeviceManagerUI
 
 									final SideBarEntrySWT	entry;
 									
-									if ( device.getType() == Device.DT_MEDIA_RENDERER ){
+									int	device_type = device.getType();
+									
+									if ( device_type == Device.DT_MEDIA_RENDERER ){
 
 										entry = 
 											side_bar.createEntryFromSkinRef(
@@ -1789,10 +2024,39 @@ DeviceManagerUI
 											entry.setImageLeftID(id);
 										}
 										
-										entry.setDatasource(device);
+									}else if ( device_type == Device.DT_OFFLINE_DOWNLOADER ){
+										
+										entry = 
+											side_bar.createEntryFromSkinRef(
+												parent,
+												key, "devicesodview",
+												device.getName(),
+												view, null, false, -1);
+										
+											
+										DeviceOfflineDownloader dod = (DeviceOfflineDownloader)device;
+										
+										String	id;
+										
+										String manufacturer = dod.getManufacturer();
+										
+										if ( manufacturer.toLowerCase().contains( "vuze" )){
+											
+											id = "vuze";
 
-									}else{
+										}else if ( manufacturer.toLowerCase().contains( "belkin" )){
+											
+											id = "bel";
+											
+										}else{
+											
+											id = "other";
+										}
+										
+										entry.setImageLeftID( "image.sidebar.device.od." + id + ".small" );
 
+									}else{
+										
 										side_bar.createTreeItemFromIView(
 												parent, 
 												view,
@@ -1805,6 +2069,8 @@ DeviceManagerUI
 										entry = SideBar.getEntry( key );
 									}
 									
+									entry.setDatasource( device );
+									
 									entry.setLogID(parent + "-" + device.getName());
 
 									new_di.setTreeItem( entry.getTreeItem(), entry );
@@ -2172,6 +2438,56 @@ DeviceManagerUI
 										}
 									}
 
+									if ( device instanceof DeviceOfflineDownloader ){
+
+										final DeviceOfflineDownloader	dod = (DeviceOfflineDownloader)device;
+										
+										need_sep = true;
+										
+										MenuItem configure_menu_item = menu_manager.addMenuItem("sidebar." + key, "device.configure");
+											
+
+										configure_menu_item.addFillListener(new MenuItemFillListener() {
+											public void menuWillBeShown(MenuItem menu, Object data) {
+												menu.setEnabled( dod.isAlive());
+											}
+										});
+
+										configure_menu_item.addListener(
+											new MenuItemListener()
+											{
+												public void 
+												selected(
+													MenuItem 	menu,
+													Object 		target ) 
+												{
+													try{
+														new DevicesODFTUX( dod );
+														
+													}catch( Throwable e ){
+														
+														Debug.out( e );
+													}
+												}
+											});
+										
+										MenuItem enabled_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.contextmenu.od.enable" );
+										
+										enabled_menu_item.setStyle(MenuItem.STYLE_CHECK);
+
+										enabled_menu_item.addFillListener(new MenuItemFillListener() {
+											public void menuWillBeShown(MenuItem menu, Object data) {
+												menu.setData(new Boolean( dod.isEnabled()));
+											}
+										});
+										
+										enabled_menu_item.addListener(new MenuItemListener() {
+											public void selected(MenuItem menu, Object target) {
+								 				dod.setEnabled((Boolean) menu.getData());
+											}
+										});
+									}
+									
 									if ( device.isBrowsable()){
 										
 										need_sep = true;
@@ -2754,7 +3070,7 @@ DeviceManagerUI
 				
 			}else if ( propertyID == TITLE_INDICATOR_TEXT ){
 			
-				if ( device_type == Device.DT_MEDIA_RENDERER ){ 
+				if ( device_type == Device.DT_MEDIA_RENDERER || device_type == Device.DT_OFFLINE_DOWNLOADER ){ 
 				
 					if ( spinner != null ){
 					
@@ -2788,9 +3104,20 @@ DeviceManagerUI
 							
 							if ( device instanceof DeviceMediaRenderer ){
 						
-								DeviceMediaRenderer	renderer = (DeviceMediaRenderer)device;
+								if ( SHOW_RENDERER_VITALITY ){
+									
+									DeviceMediaRenderer	renderer = (DeviceMediaRenderer)device;
+									
+									last_indicator += renderer.getCopyToDevicePending() + renderer.getCopyToFolderPending();
+								}
+							}else if ( device instanceof DeviceOfflineDownloader ){
 								
-								last_indicator += renderer.getCopyToDevicePending() + renderer.getCopyToFolderPending();
+								if ( SHOW_OD_VITALITY ){
+									
+									DeviceOfflineDownloader dod = (DeviceOfflineDownloader)device;
+									
+									last_indicator += dod.getTransferingCount();
+								}
 							}
 						}
 						
@@ -2813,11 +3140,8 @@ DeviceManagerUI
 						}
 						
 						if ( last_indicator > 0 ){
-							
-							if ( SHOW_VITALITY ){
-							
-								return( String.valueOf( last_indicator ));
-							}
+														
+							return( String.valueOf( last_indicator ));
 						}
 					}else{
 						
@@ -2826,14 +3150,16 @@ DeviceManagerUI
 					}
 				}
 			}else if ( propertyID == TITLE_INDICATOR_COLOR ){
-					
+				
+				/*
 				if ( last_indicator > 0 ){
-					
+				
 					if ( SHOW_VITALITY ){
 					
 						return( to_copy_indicator_colors );
 					}
 				}
+				*/
 			}
 			
 			return null;
@@ -3001,20 +3327,29 @@ DeviceManagerUI
 				
 				if ( device instanceof DeviceMediaRenderer ){
 					
-					DeviceMediaRenderer	renderer = (DeviceMediaRenderer)device;
+					if ( SHOW_RENDERER_VITALITY ){
 					
-					last_indicator = renderer.getCopyToDevicePending() + renderer.getCopyToFolderPending();
+						DeviceMediaRenderer	renderer = (DeviceMediaRenderer)device;
 					
-					if ( last_indicator > 0 ){
-						
-						if ( SHOW_VITALITY ){
-						
-							return( String.valueOf( last_indicator ));
-						}
+					
+						last_indicator = renderer.getCopyToDevicePending() + renderer.getCopyToFolderPending();
+					}
+				}else if ( device instanceof DeviceOfflineDownloader ){
+					
+					if ( SHOW_OD_VITALITY ){
+					
+						DeviceOfflineDownloader	dod = (DeviceOfflineDownloader)device;
+					
+						last_indicator = dod.getTransferingCount();
 					}
 				}
+				
+				if ( last_indicator > 0 ){
+										
+					return( String.valueOf( last_indicator ));
+				}
 			}else if ( propertyID == TITLE_INDICATOR_COLOR ){
-					
+				/*	
 				if ( last_indicator > 0 ){
 						
 					if ( SHOW_VITALITY ){
@@ -3022,6 +3357,7 @@ DeviceManagerUI
 						return( to_copy_indicator_colors );
 					}
 				}
+				*/
 			}else if ( propertyID == TITLE_ACTIVE_STATE ){
 
 				if ( device.isLivenessDetectable()){
diff --git a/com/aelitis/azureus/ui/swt/devices/DevicesFTUX.java b/com/aelitis/azureus/ui/swt/devices/DevicesFTUX.java
index 2dbb4de..6f811f4 100644
--- a/com/aelitis/azureus/ui/swt/devices/DevicesFTUX.java
+++ b/com/aelitis/azureus/ui/swt/devices/DevicesFTUX.java
@@ -49,6 +49,7 @@ import com.aelitis.azureus.core.devices.DeviceManager;
 import com.aelitis.azureus.core.devices.DeviceManagerFactory;
 import com.aelitis.azureus.core.messenger.config.PlatformDevicesMessenger;
 import com.aelitis.azureus.ui.swt.browser.BrowserContext;
+import com.aelitis.azureus.ui.swt.browser.listener.*;
 import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
 import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
 import com.aelitis.azureus.util.ConstantsVuze;
@@ -104,14 +105,21 @@ public class DevicesFTUX
 	private void open() {
 		// This is a simple dialog box, so instead of using SkinnedDialog, we'll
 		// just built it old school
-		shell = ShellFactory.createShell(Utils.findAnyShell(), SWT.DIALOG_TRIM);
+		shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM);
 		shell.setText(MessageText.getString("devices.turnon.title"));
 
 		Utils.setShellIcon(shell);
 
 		try {
-			browser = new Browser(shell, Utils.getInitialBrowserStyle(SWT.NONE));
-			new BrowserContext("DevicesFTUX", browser, null, true);
+			browser = Utils.createSafeBrowser(shell, SWT.NONE);
+			if (browser != null) {
+  			BrowserContext context = new BrowserContext("DevicesFTUX", browser, null, true);
+  
+  			context.addMessageListener(new TorrentListener());
+  			context.addMessageListener(new VuzeListener());
+  			context.addMessageListener(new DisplayListener(browser));
+  			context.addMessageListener(new ConfigListener(browser));
+			}
 		} catch (Throwable t) {
 		}
 
diff --git a/com/aelitis/azureus/ui/swt/devices/DevicesODFTUX.java b/com/aelitis/azureus/ui/swt/devices/DevicesODFTUX.java
new file mode 100644
index 0000000..52dd7d0
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/devices/DevicesODFTUX.java
@@ -0,0 +1,462 @@
+/**
+ * Created on Mar 7, 2009
+ *
+ * Copyright 2008 Vuze, Inc.  All rights reserved.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
+ */
+
+package com.aelitis.azureus.ui.swt.devices;
+
+
+import java.net.URLEncoder;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.Debug;
+
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.LinkLabel;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
+import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+
+import com.aelitis.azureus.core.devices.DeviceManagerException;
+import com.aelitis.azureus.core.devices.DeviceOfflineDownloader;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
+
+/**
+ * @author TuxPaper
+ * @created Mar 7, 2009
+ *
+ */
+public class 
+DevicesODFTUX
+{
+	private static final String URL_LEARN_MORE = "http://www.vuze.com/devices/offlinedownloader.start";
+
+	private DeviceOfflineDownloader		device;
+	
+	private Display display;
+
+	private Shell shell;
+		
+	private Font boldFont;
+	private Font titleFont;
+	private Font subTitleFont;
+	private Font textInputFont;
+	
+	private Button turnOnButton;
+	
+	private String		dev_image_key;
+	private ImageLoader imageLoader;
+
+	protected
+	DevicesODFTUX(
+		DeviceOfflineDownloader		_device )
+	
+		throws DeviceManagerException
+	{
+		device	= _device;
+		
+		final long avail = device.getSpaceAvailable();
+			
+		Utils.execSWTThread(
+			new AERunnable() 
+			{
+				public void
+				runSupport()
+				{
+					open( avail == 0 );
+				}
+			});
+	}
+
+
+	private void 
+	open(
+		boolean		no_space_available )
+	{
+		imageLoader = ImageLoader.getInstance();
+
+		shell = ShellFactory.createMainShell(SWT.TITLE | SWT.CLOSE | SWT.RESIZE);
+		
+		shell.setSize(650,400);
+		
+		Utils.centreWindow(shell);
+		
+		shell.setMinimumSize(550,400);
+		
+		display = shell.getDisplay();
+		
+		Utils.setShellIcon(shell);
+		
+		createFonts();
+		
+		shell.setText(MessageText.getString("devices.activation"));
+		
+		shell.addListener(SWT.Dispose, new Listener() {
+			public void handleEvent(Event event) {
+
+				imageLoader.releaseImage("wizard_header_bg");
+				
+				if ( dev_image_key != null ){
+					
+					imageLoader.releaseImage( dev_image_key );
+				}
+				
+				if(titleFont != null && !titleFont.isDisposed()) {
+					titleFont.dispose();
+				}
+				
+				if(textInputFont != null && !textInputFont.isDisposed()) {
+					textInputFont.dispose();
+				}
+				
+				if(boldFont != null && !boldFont.isDisposed()) {
+					boldFont.dispose();
+				}
+				
+				if(subTitleFont != null && !subTitleFont.isDisposed()) {
+					subTitleFont.dispose();
+				}
+			}
+		});
+		
+		Composite header = new Composite(shell, SWT.NONE);
+		header.setBackgroundMode(SWT.INHERIT_DEFAULT);
+		header.setBackgroundImage(imageLoader.getImage("wizard_header_bg"));
+		
+		Label topSeparator = new Label(shell,SWT.SEPARATOR |SWT.HORIZONTAL);
+		
+		Composite main = new Composite(shell, SWT.NONE);
+		
+		main.setBackground( Colors.white );
+		
+		Label bottomSeparator = new Label(shell,SWT.SEPARATOR |SWT.HORIZONTAL);
+		
+		Composite footer = new Composite(shell, SWT.NONE);
+		
+		FormLayout layout = new FormLayout();
+		shell.setLayout(layout);
+		
+		FormData data;
+		
+		data = new FormData();
+		data.top = new FormAttachment(0,0);
+		data.left = new FormAttachment(0,0);
+		data.right = new FormAttachment(100,0);
+		//data.height = 50;
+		header.setLayoutData(data);
+		
+		data = new FormData();
+		data.top = new FormAttachment(header,0);
+		data.left = new FormAttachment(0,0);
+		data.right = new FormAttachment(100,0);
+		topSeparator.setLayoutData(data);
+		
+		data = new FormData();
+		data.top = new FormAttachment(topSeparator,0);
+		data.left = new FormAttachment(0,0);
+		data.right = new FormAttachment(100,0);
+		data.bottom = new FormAttachment(bottomSeparator,0);
+		main.setLayoutData(data);
+		
+		data = new FormData();
+		data.left = new FormAttachment(0,0);
+		data.right = new FormAttachment(100,0);
+		data.bottom = new FormAttachment(footer,0);
+		bottomSeparator.setLayoutData(data);
+		
+		data = new FormData();
+		data.bottom = new FormAttachment(100,0);
+		data.left = new FormAttachment(0,0);
+		data.right = new FormAttachment(100,0);
+		footer.setLayoutData(data);
+		
+		populateHeader(header);
+		
+		populateMain( main, no_space_available );
+		
+		populateFooter(footer);
+			
+		shell.setDefaultButton(turnOnButton);
+
+		shell.layout();
+		
+		Utils.centreWindow(shell);
+		
+		turnOnButton.setFocus();
+		
+		shell.open();
+	}
+
+	private void 
+	populateHeader(
+		Composite header) 
+	{
+		header.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
+		
+		Label title = new Label(header, SWT.WRAP);
+		
+		title.setFont(titleFont);
+		
+		title.setText( MessageText.getString("devices.turnon.title") );
+		
+		FillLayout layout = new FillLayout();
+		
+		layout.marginHeight = 10;
+		
+		layout.marginWidth = 10;
+		
+		header.setLayout(layout); 
+	}
+	
+
+	private void 
+	populateMain(
+		Composite 	main,
+		boolean		no_space_available )
+	{
+		String manufacturer = device.getManufacturer();
+		
+		boolean	is_belkin = manufacturer.toLowerCase().contains( "belkin");
+				
+		Label image_area = new Label(main, SWT.NONE);
+		
+		String	router_text;
+		
+		if ( is_belkin ){
+			
+			dev_image_key = "image.device.logo.belkin";
+			
+			router_text = MessageText.getString( "devices.router" );
+			
+		}else{
+			router_text = MessageText.getString( "devices.od" );
+		}
+		
+		if ( dev_image_key != null ){
+			image_area.setImage(imageLoader.getImage( dev_image_key ));
+		}
+		
+		Label text1 = new Label(main, SWT.WRAP);
+		text1.setBackground( Colors.white );
+		text1.setFont( textInputFont );
+		text1.setText( MessageText.getString("devices.od.turnon.text1", new String[]{ (is_belkin?"Belkin":"Vuze" ) + " " + router_text }));
+
+		Label text2 = new Label(main, SWT.WRAP);
+		text2.setBackground( Colors.white );
+		text2.setFont( textInputFont );
+		text2.setText( MessageText.getString("devices.od.turnon.text2", new String[]{ router_text }));
+		
+		Label text3 = new Label(main, SWT.WRAP);
+		text3.setBackground( Colors.white );
+		text3.setFont( textInputFont );
+		text3.setText( MessageText.getString("devices.od.turnon.text3", new String[]{ router_text }));
+		text3.setForeground( Colors.red );
+		text3.setVisible( no_space_available );
+
+		Label link = new Label(main, SWT.WRAP);
+		link.setBackground( Colors.white );
+		link.setFont( textInputFont );
+		link.setText( MessageText.getString("devices.od.turnon.learn") );
+		
+		String url = URL_LEARN_MORE;
+		
+		try{
+			url += "?man=" + URLEncoder.encode( manufacturer, "UTF-8" );
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+		
+		LinkLabel.makeLinkedLabel( link, url );
+		
+		
+		FormLayout layout = new FormLayout();
+		layout.marginHeight = 5;
+		layout.marginWidth = 50;
+		layout.spacing = 5;
+		
+		main.setLayout(layout);
+		FormData data;
+		
+		data = new FormData();
+		data.top = new FormAttachment(0, 20);
+		data.left = new FormAttachment(0);
+		image_area.setLayoutData(data);
+		
+		data = new FormData();
+		data.top = new FormAttachment(image_area,10);
+		data.left = new FormAttachment(0);
+		data.right = new FormAttachment(100);
+		text1.setLayoutData(data);
+		
+		data = new FormData();
+		data.top = new FormAttachment(text1, 10 );
+		data.left = new FormAttachment(0);
+		data.right = new FormAttachment(100);
+		text2.setLayoutData(data);
+		
+		data = new FormData();
+		data.top = new FormAttachment(text2, 10 );
+		data.left = new FormAttachment(0);
+		data.right = new FormAttachment(100);
+		text3.setLayoutData(data);
+		
+		data = new FormData();
+		data.top = new FormAttachment(text3, 10 );
+		data.left = new FormAttachment(0);
+		link.setLayoutData(data);
+	}
+	
+
+	
+	private void 
+	createFonts() 
+	{	
+		FontData[] fDatas = shell.getFont().getFontData();
+		
+		for(int i = 0 ; i < fDatas.length ; i++) {
+			fDatas[i].setStyle(SWT.BOLD);
+		}
+		boldFont = new Font(display,fDatas);
+		
+		
+		for(int i = 0 ; i < fDatas.length ; i++) {
+			if(org.gudy.azureus2.core3.util.Constants.isOSX) {
+				fDatas[i].setHeight(12);
+			} else {
+				fDatas[i].setHeight(10);
+			}
+		}
+		subTitleFont = new Font(display,fDatas);
+		
+		for(int i = 0 ; i < fDatas.length ; i++) {
+			if(org.gudy.azureus2.core3.util.Constants.isOSX) {
+				fDatas[i].setHeight(17);
+			} else {
+				fDatas[i].setHeight(14);
+			}
+		}
+		titleFont = new Font(display,fDatas);
+		
+		
+		for(int i = 0 ; i < fDatas.length ; i++) {
+			if(org.gudy.azureus2.core3.util.Constants.isOSX) {
+				fDatas[i].setHeight(14);
+			} else {
+				fDatas[i].setHeight(12);
+			}
+			fDatas[i].setStyle(SWT.NONE);
+		}
+		textInputFont = new Font(display,fDatas);	
+	}
+	
+	private void 
+	populateFooter(
+		Composite footer) 
+	{
+		final Button	dont_ask_again = new Button( footer, SWT.CHECK );
+		dont_ask_again.setText(MessageText.getString("general.dont.ask.again"));
+		dont_ask_again.setSelection( true );
+		
+		Button cancelButton = new Button(footer,SWT.PUSH);
+		cancelButton.setText(MessageText.getString("button.nothanks"));
+			
+		turnOnButton = new Button(footer,SWT.PUSH);
+		turnOnButton.setText(MessageText.getString("Button.turnon"));
+		
+		
+		FormLayout layout = new FormLayout();
+		layout.marginHeight = 5;
+		layout.marginWidth = 5;
+		layout.spacing = 5;
+		
+		footer.setLayout(layout);
+		FormData data;
+			
+		data = new FormData();
+		data.left = new FormAttachment(0,50);
+		data.width = 100;
+		dont_ask_again.setLayoutData(data);
+
+		data = new FormData();
+		data.right = new FormAttachment(100);
+		data.width = 100;
+		cancelButton.setLayoutData(data);
+		
+		data = new FormData();
+		data.right = new FormAttachment( cancelButton );
+		data.width = 100;
+		turnOnButton.setLayoutData(data);
+		
+		
+		
+		turnOnButton.addListener(
+			SWT.Selection, 
+			new Listener() 
+			{	
+				public void 
+				handleEvent(
+					Event arg0 ) 
+				{
+				
+					device.setEnabled( true );
+					
+					device.setShownFTUX();
+					
+					shell.close();
+				}
+			});
+				
+		cancelButton.addListener(
+			SWT.Selection, 
+			new Listener() 
+			{
+				public void 
+				handleEvent(
+					Event arg0 )
+				{
+					device.setEnabled( false );
+					
+					if ( dont_ask_again.getSelection()){
+						
+						device.setShownFTUX();
+					}
+					
+					shell.close();
+				}
+			});
+	}
+
+	protected void close() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (shell != null && !shell.isDisposed()) {
+					shell.dispose();
+				}
+			}
+		});
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/devices/DevicesWizard.java b/com/aelitis/azureus/ui/swt/devices/DevicesWizard.java
index e9da0b3..c57f6b8 100644
--- a/com/aelitis/azureus/ui/swt/devices/DevicesWizard.java
+++ b/com/aelitis/azureus/ui/swt/devices/DevicesWizard.java
@@ -9,14 +9,12 @@ import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.DebugLight;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 
 
 import com.aelitis.azureus.core.devices.Device;
 import com.aelitis.azureus.core.devices.DeviceTemplate;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
 public class 
@@ -52,26 +50,12 @@ DevicesWizard
 		
 		imageLoader = ImageLoader.getInstance();
 				
-		UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		shell = ShellFactory.createMainShell(SWT.TITLE | SWT.CLOSE | SWT.ICON
+				| SWT.RESIZE);
 		
-		if ( functionsSWT != null ){
+		shell.setSize(650,400);
 			
-			Shell mainShell = functionsSWT.getMainShell();
-			
-			shell = new Shell(mainShell,SWT.TITLE | SWT.CLOSE | SWT.ICON | SWT.RESIZE);
-			
-			shell.setSize(650,400);
-			
-			Utils.centerWindowRelativeTo(shell, mainShell);
-			
-		}else{
-			
-			shell = new Shell(SWT.TITLE | SWT.CLOSE | SWT.RESIZE);
-			
-			shell.setSize(650,400);
-			
-			Utils.centreWindow(shell);
-		}
+		Utils.centreWindow(shell);
 		
 		shell.setMinimumSize(550,400);
 		
diff --git a/com/aelitis/azureus/ui/swt/devices/SBC_DevicesODView.java b/com/aelitis/azureus/ui/swt/devices/SBC_DevicesODView.java
new file mode 100644
index 0000000..7ea9dd0
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/devices/SBC_DevicesODView.java
@@ -0,0 +1,615 @@
+/**
+ * Created on Feb 24, 2009
+ *
+ * Copyright 2008 Vuze, Inc.  All rights reserved.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
+ */
+
+package com.aelitis.azureus.ui.swt.devices;
+
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.swt.SWT;
+
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+import org.gudy.azureus2.plugins.ui.tables.TableColumnCreationListener;
+import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.ui.swt.*;
+
+import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.core.devices.Device;
+import com.aelitis.azureus.core.devices.DeviceListener;
+import com.aelitis.azureus.core.devices.DeviceOfflineDownload;
+import com.aelitis.azureus.core.devices.DeviceOfflineDownloader;
+import com.aelitis.azureus.core.devices.DeviceOfflineDownloaderListener;
+import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.common.updater.UIUpdatable;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+import com.aelitis.azureus.ui.swt.columns.torrent.ColumnThumbnail;
+import com.aelitis.azureus.ui.swt.devices.columns.*;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
+import com.aelitis.azureus.ui.swt.views.skin.SkinView;
+import com.aelitis.azureus.ui.swt.views.skin.SkinViewManager;
+import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
+import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
+
+
+public class 
+SBC_DevicesODView
+	extends SkinView
+	implements UIUpdatable, IconBarEnabler
+{
+	public static final String TABLE_RCM = "DevicesOD";
+
+	private static boolean columnsAdded = false;
+	
+	private DeviceOfflineDownloader		device;
+	
+	private TableViewSWTImpl<DeviceOfflineDownload> tv_downloads;
+
+	private SideBarEntrySWT 	sidebar_entry;
+	private Composite			control_parent;
+	
+
+	public Object 
+	skinObjectInitialShow(
+		SWTSkinObject skinObject, Object params ) 
+	{
+		AzureusCoreFactory.addCoreRunningListener(
+			new AzureusCoreRunningListener() 
+			{
+				public void 
+				azureusCoreRunning(
+					AzureusCore core )
+				{					
+					initColumns( core );
+				}
+			});
+
+		SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
+		
+		if ( sidebar != null ){
+			
+			sidebar_entry = sidebar.getCurrentEntry();
+			
+			sidebar_entry.setIconBarEnabler( this );
+			
+			device = (DeviceOfflineDownloader)sidebar_entry.getDatasource();
+		}
+		
+		return null;
+	}
+
+
+	private void 
+	initColumns(
+		AzureusCore core ) 
+	{
+		synchronized( SBC_DevicesODView.class ){
+			
+			if ( columnsAdded ){
+			
+				return;
+			}
+		
+			columnsAdded = true;
+		}
+		
+		UIManager uiManager = PluginInitializer.getDefaultInterface().getUIManager();
+		
+		TableManager tableManager = uiManager.getTableManager();
+		
+		tableManager.registerColumn( 
+			DeviceOfflineDownload.class, ColumnThumbnail.COLUMN_ID,
+			new TableColumnCreationListener() {
+				public void tableColumnCreated(TableColumn column) {
+					new ColumnThumbnail(column);
+					column.setWidth(70);
+				}
+			});
+
+		tableManager.registerColumn( 
+			DeviceOfflineDownload.class, ColumnOD_Name.COLUMN_ID,
+			new TableColumnCreationListener() {
+				public void tableColumnCreated(TableColumn column) {
+					new ColumnOD_Name(column);
+				}
+			});
+		
+		tableManager.registerColumn( 
+			DeviceOfflineDownload.class, ColumnOD_Status.COLUMN_ID,
+			new TableColumnCreationListener() {
+				public void tableColumnCreated(TableColumn column) {
+					new ColumnOD_Status(column);
+				}
+			});
+		
+		tableManager.registerColumn( 
+				DeviceOfflineDownload.class, ColumnOD_Completion.COLUMN_ID,
+				new TableColumnCreationListener() {
+					public void tableColumnCreated(TableColumn column) {
+						new ColumnOD_Completion(column);
+					}
+				});
+		
+		tableManager.registerColumn( 
+				DeviceOfflineDownload.class, ColumnOD_Remaining.COLUMN_ID,
+				new TableColumnCreationListener() {
+					public void tableColumnCreated(TableColumn column) {
+						new ColumnOD_Remaining(column);
+					}
+				});
+	}
+
+	public Object 
+	skinObjectShown(
+		SWTSkinObject 	skinObject, 
+		Object 			params ) 
+	{
+		super.skinObjectShown(skinObject, params);
+
+		SWTSkinObject so_list = getSkinObject("devicesod-list");
+		
+		if ( so_list != null ){
+			
+			initTable((Composite) so_list.getControl());
+		}
+		
+		return null;
+	}
+
+	public Object 
+	skinObjectHidden(
+		SWTSkinObject 	skinObject, 
+		Object 			params ) 
+	{
+		synchronized( this ){
+			
+			if ( tv_downloads != null ){
+				
+				tv_downloads.delete();
+				
+				tv_downloads = null;
+			}
+		}
+		
+		Utils.disposeSWTObjects(new Object[] {
+				control_parent,
+		});
+
+		return( super.skinObjectHidden(skinObject, params));
+	}
+
+	public Object
+	skinObjectDestroyed(
+		SWTSkinObject 	skinObject, 
+		Object 			params ) 
+	{
+		synchronized( this ){
+			
+			if ( tv_downloads != null ){
+				
+				tv_downloads.delete();
+				
+				tv_downloads = null;
+			}
+		}
+		
+		Utils.disposeSWTObjects(new Object[] {
+				control_parent,
+		});
+
+		return( super.skinObjectDestroyed(skinObject, params));
+	}
+	
+	private void 
+	initTable(
+		final Composite control ) 
+	{	
+		control_parent = new Composite(control, SWT.NONE);
+		control_parent.setLayoutData(Utils.getFilledFormData());
+		
+		final StackLayout stack_layout = new StackLayout();
+		
+		control_parent.setLayout( stack_layout );
+		
+			// enabled
+		
+		final Composite enabled_device_parent = new Composite( control_parent, SWT.NONE);
+
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = layout.marginWidth = layout.verticalSpacing = layout.horizontalSpacing = 0;
+		enabled_device_parent.setLayout(layout);
+			
+		tv_downloads = 
+			new TableViewSWTImpl<DeviceOfflineDownload>(
+					DeviceOfflineDownload.class, 
+					TABLE_RCM,
+					TABLE_RCM, 
+					new TableColumnCore[0], 
+					ColumnOD_Name.COLUMN_ID, 
+					SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL );
+
+		tv_downloads.setRowDefaultHeight(50);
+		tv_downloads.setHeaderVisible(true);
+
+		tv_downloads.addSelectionListener(
+			new TableSelectionListener() 
+			{
+				public void 
+				selected(
+					TableRowCore[] row ) 
+				{
+					refreshIconBar();
+				}
+	
+				public void 
+				mouseExit(
+					TableRowCore row ) 
+				{
+				}
+	
+				public void 
+				mouseEnter(
+					TableRowCore row )
+				{
+				}
+	
+				public void 
+				focusChanged(
+					TableRowCore focus ) 
+				{
+					refreshIconBar();
+				}
+	
+				public void 
+				deselected(
+					TableRowCore[] rows) 
+				{
+					refreshIconBar();
+				}
+	
+				public void 
+				defaultSelected(TableRowCore[] rows, int stateMask)
+				{
+					refreshIconBar();
+				}
+				
+				protected void
+				refreshIconBar()
+				{
+					SelectedContentManager.clearCurrentlySelectedContent();
+					
+					UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+					if (uiFunctions != null) {
+						uiFunctions.refreshIconBar();
+					}
+				}
+			}, false );
+		
+		tv_downloads.addLifeCycleListener(
+			new TableLifeCycleListener() 
+			{
+				private final TableViewSWTImpl<DeviceOfflineDownload>	f_table = tv_downloads;
+				
+				private Set<DeviceOfflineDownload>	download_set = new HashSet<DeviceOfflineDownload>();
+				
+				private boolean destroyed;
+				
+				private DeviceOfflineDownloaderListener od_listener = 
+					new DeviceOfflineDownloaderListener()
+					{
+						public void
+						downloadAdded(
+							final DeviceOfflineDownload 	download )
+						{	
+							synchronized( download_set ){
+								
+								if ( destroyed ){
+									
+									return;
+								}							
+							
+								if ( download_set.contains( download )){
+									
+									return;
+								}
+								
+								download_set.add( download );
+							}
+							
+							Utils.execSWTThread(
+									new Runnable()
+									{
+										public void
+										run()
+										{
+											if ( tv_downloads == f_table && !f_table.isDisposed()){
+												
+												synchronized( download_set ){
+													
+													if ( destroyed ){
+														
+														return;
+													}
+												}
+												
+												f_table.addDataSources( new DeviceOfflineDownload[]{ download });
+											}
+										}
+									});
+						}
+
+						public void
+						downloadChanged(
+							final DeviceOfflineDownload	download )
+						{
+							synchronized( download_set ){
+								
+								if ( destroyed ){
+									
+									return;
+								}							
+							
+								if ( !download_set.contains( download )){
+									
+									return;
+								}
+							}
+							
+							Utils.execSWTThread(
+									new Runnable()
+									{
+										public void
+										run()
+										{
+											if ( tv_downloads == f_table && !f_table.isDisposed()){
+													
+												synchronized( download_set ){
+													
+													if ( destroyed ){
+														
+														return;
+													}
+												}
+												
+												TableRowCore row = f_table.getRow( download );
+												
+												if ( row != null ){
+												
+													row.refresh(true );
+												}
+											}
+										}
+									});
+						}
+						
+						public void
+						downloadRemoved(
+							final DeviceOfflineDownload	download )
+						{
+							synchronized( download_set ){
+								
+								if ( destroyed ){
+									
+									return;
+								}							
+							
+								if ( !download_set.remove( download )){
+									
+									return;
+								}
+							}
+							
+							Utils.execSWTThread(
+									new Runnable()
+									{
+										public void
+										run()
+										{
+											if ( tv_downloads == f_table && !f_table.isDisposed()){
+													
+												synchronized( download_set ){
+													
+													if ( destroyed ){
+														
+														return;
+													}
+												}
+												
+												f_table.removeDataSources( new DeviceOfflineDownload[]{ download });
+											}
+										}
+									});
+						}
+					};
+				
+				public void 
+				tableViewInitialized() 
+				{
+					device.addListener( od_listener );
+					
+					DeviceOfflineDownload[] downloads = device.getDownloads();
+					
+					final ArrayList<DeviceOfflineDownload>	new_downloads = new ArrayList<DeviceOfflineDownload>( downloads.length );
+
+					synchronized( download_set ){
+										
+						if ( destroyed ){
+							
+							return;
+						}
+												
+						for ( DeviceOfflineDownload download: downloads ){
+							
+							if ( !download_set.contains( download )){
+	
+								download_set.add( download );
+								
+								new_downloads.add( download );
+							}
+						}
+					}
+					
+					if ( new_downloads.size() > 0 ){
+												
+						Utils.execSWTThread(
+							new Runnable()
+							{
+								public void
+								run()
+								{
+									if ( tv_downloads == f_table && !f_table.isDisposed()){
+									
+										synchronized( download_set ){
+											
+											if ( destroyed ){
+												
+												return;
+											}
+										}
+										
+										f_table.addDataSources( new_downloads.toArray( new DeviceOfflineDownload[ new_downloads.size()]));
+									}
+								}
+							});
+					}
+				}
+
+				public void 
+				tableViewDestroyed() 
+				{
+					device.removeListener( od_listener );
+
+					synchronized( download_set ){
+						
+						destroyed = true;
+					
+						download_set.clear();
+					}
+				}
+			});
+
+		tv_downloads.initialize( enabled_device_parent );	
+			
+			// disabled
+		
+		final Composite disabled_device_parent = new Composite( control_parent, SWT.NONE);
+	
+		layout = new GridLayout();
+		layout.marginHeight = layout.marginWidth = layout.verticalSpacing = layout.horizontalSpacing = 0;
+		disabled_device_parent.setLayout(layout);
+
+		Label l = new Label( disabled_device_parent, SWT.NULL );
+		GridData grid_data = new GridData( GridData.FILL_HORIZONTAL );
+		grid_data.horizontalIndent = 5;
+		l.setLayoutData( grid_data );
+		
+		l.setText( MessageText.getString( "device.is.disabled" ));
+	
+		device.addListener(
+			new DeviceListener()
+			{
+				public void 
+				deviceChanged(
+					Device d )
+				{
+					Composite x = device.isEnabled()?enabled_device_parent:disabled_device_parent;
+
+					if ( x.isDisposed()){
+						
+						device.removeListener( this );
+						
+					}else{
+					
+						if ( x != stack_layout.topControl ){
+							
+							Utils.execSWTThread(
+								new Runnable()
+								{
+									public void
+									run()
+									{
+										Composite x = device.isEnabled()?enabled_device_parent:disabled_device_parent;
+										
+										if ( !x.isDisposed() && x != stack_layout.topControl ){
+											
+											stack_layout.topControl = x;
+											
+											control.layout( true, true );
+										}
+									}
+								});
+						}
+					}
+				}
+			});
+		
+		stack_layout.topControl = device.isEnabled()?enabled_device_parent:disabled_device_parent;
+		
+		control.layout(true);
+	}	
+	
+	public boolean 
+	isEnabled(
+		String key )
+	{
+		return( false );
+	}
+	
+	public boolean 
+	isSelected(
+		String key )
+	{
+		return( false );
+	}
+	
+	public void 
+	itemActivated(
+		String key )
+	{
+	}
+	
+	public String 
+	getUpdateUIName() 
+	{
+		return( "DevicesODView" );
+	}
+
+	public void 
+	updateUI() 
+	{
+		if ( tv_downloads != null ){
+			
+			tv_downloads.refreshTable( false );
+		}
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/devices/SBC_DevicesView.java b/com/aelitis/azureus/ui/swt/devices/SBC_DevicesView.java
index a3d5614..eec2c61 100644
--- a/com/aelitis/azureus/ui/swt/devices/SBC_DevicesView.java
+++ b/com/aelitis/azureus/ui/swt/devices/SBC_DevicesView.java
@@ -21,6 +21,7 @@ package com.aelitis.azureus.ui.swt.devices;
 import java.io.File;
 import java.net.URL;
 import java.util.*;
+import java.util.List;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.*;
@@ -56,10 +57,10 @@ import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.devices.*;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 import com.aelitis.azureus.ui.common.table.*;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
-import com.aelitis.azureus.ui.swt.columns.torrent.ColumnAzProduct;
 import com.aelitis.azureus.ui.swt.columns.torrent.ColumnThumbnail;
 import com.aelitis.azureus.ui.swt.devices.columns.*;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility;
@@ -235,13 +236,6 @@ public class SBC_DevicesView
 						}
 					}
 				});
-		tableManager.registerColumn(TranscodeFile.class, ColumnAzProduct.COLUMN_ID,
-				new TableColumnCreationListener() {
-					public void tableColumnCreated(TableColumn column) {
-						new ColumnAzProduct(column);
-						column.setWidth(42);
-					}
-				});
 		tableManager.registerColumn(TranscodeFile.class, ColumnThumbnail.COLUMN_ID,
 				new TableColumnCreationListener() {
 					public void tableColumnCreated(TableColumn column) {
@@ -558,24 +552,22 @@ public class SBC_DevicesView
 				{
 					if ( e.stateMask == 0 && e.keyCode == SWT.DEL ){
 						
-						Object[] selected;
+						TranscodeFile[] selected;
 						
 						synchronized (this) {
 							
 							if ( tvFiles == null ){
 								
-								selected = new Object[0];
+								selected = new TranscodeFile[0];
 								
 							}else{
 							
-								selected = tvFiles.getSelectedDataSources().toArray();
+								List<TranscodeFile> selectedDataSources = tvFiles.getSelectedDataSources();
+								selected = selectedDataSources.toArray(new TranscodeFile[0]);
 							}
 						}
 						
-						for (Object ds : selected) {
-							
-							deleteFile((TranscodeFile)ds);
-						}
+						deleteFiles(selected, 0);
 						
 						e.doit = false;
 					}
@@ -812,10 +804,7 @@ public class SBC_DevicesView
 
 		remove_item.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent e) {
-				for (TranscodeFile file : files) {
-
-					deleteFile(file);
-				}
+				deleteFiles(files, 0);
 			};
 		});
 
@@ -1139,16 +1128,14 @@ public class SBC_DevicesView
 			return;
 		}
 
-		Object[] selectedDS = tvFiles.getSelectedDataSources().toArray();
-		int size = tvFiles.size(false);
+		TranscodeFile[] selectedDS = tvFiles.getSelectedDataSources().toArray(new TranscodeFile[0]);
 		if (selectedDS.length == 0) {
 			return;
 		}
 
 		if (itemKey.equals("remove")) {
-			for (Object ds : selectedDS) {
-				deleteFile((TranscodeFile) ds);
-			}
+			deleteFiles(selectedDS, 0);
+			return;
 		}
 
 		java.util.List<TranscodeJob> jobs = new ArrayList<TranscodeJob>(
@@ -1256,16 +1243,17 @@ public class SBC_DevicesView
 		}
 	}
 
-	protected void deleteFile(TranscodeFile file) {
-		if (tvFiles == null || tvFiles.isDisposed()) {
-
+	protected void deleteFiles(final TranscodeFile[] toRemove, final int startIndex) {
+		if (toRemove[startIndex] == null) {
+			int nextIndex = startIndex + 1;
+			if (nextIndex < toRemove.length) {
+				deleteFiles(toRemove, nextIndex);
+			}
 			return;
 		}
 
+		final TranscodeFile file = toRemove[startIndex];
 		try {
-			boolean do_delete = false;
-
-			// we are already on SWT thread
 
 			File cache_file = file.getCacheFileIfExists();
 
@@ -1301,14 +1289,24 @@ public class SBC_DevicesView
 							copy_text
 						});
 
-				MessageBoxShell mb = new MessageBoxShell(
-						tvFiles.getComposite().getShell(), title, text, new String[] {
-							MessageText.getString("Button.yes"),
-							MessageText.getString("Button.no"),
-						}, 1, "xcode.deletedata.noconfirm.key",
-						MessageText.getString("deletedata.noprompt"), false, 0);
+				MessageBoxShell mb = new MessageBoxShell(title, text);
+				mb.setRemember("xcode.deletedata.noconfirm.key", false,
+						MessageText.getString("deletedata.noprompt"));
 
-				mb.setRememberOnlyIfButton(0);
+				if (startIndex == toRemove.length - 1) {
+  				mb.setButtons(0, new String[] {
+  					MessageText.getString("Button.yes"),
+  					MessageText.getString("Button.no"),
+  				}, new Integer[] { 0, 1 });
+  				mb.setRememberOnlyIfButton(0);
+				} else {
+  				mb.setButtons(1, new String[] {
+  					MessageText.getString("Button.removeAll"),
+  					MessageText.getString("Button.yes"),
+  					MessageText.getString("Button.no"),
+  				}, new Integer[] { 2, 0, 1 });
+  				mb.setRememberOnlyIfButton(1);
+				}
 
 				DownloadManager dm = null;
 
@@ -1319,30 +1317,49 @@ public class SBC_DevicesView
 
 				mb.setLeftImage(SWT.ICON_WARNING);
 
-				int result = mb.open();
+				mb.open(new UserPrompterResultListener() {
+					public void prompterClosed(int result) {
+						if (result == -1) {
+							return;
+						} else if (result == 0) {
+							deleteNoCheck(file);
+						} else if (result == 2) {
+							for (int i = startIndex; i < toRemove.length; i++) {
+								if (toRemove[i] != null) {
+									deleteNoCheck(toRemove[i]);
+								}
+							}
+							return;
+						}
 
-				if (result == 0) {
+						int nextIndex = startIndex + 1;
+						if (nextIndex < toRemove.length) {
+							deleteFiles(toRemove, nextIndex);
+						}
+					}
+				});
 
-					do_delete = true;
-				}
 			} else {
 
-				do_delete = true;
+				deleteNoCheck(file);
 			}
+		} catch (Throwable e) {
 
-			if (do_delete) {
-
-				TranscodeJob job = file.getJob();
-
-				if (job != null) {
+			Debug.out(e);
+		}
+	}
+	
+	private void deleteNoCheck(TranscodeFile file) {
+		TranscodeJob job = file.getJob();
 
-					job.remove();
-				}
+		if (job != null) {
 
-				file.delete(cache_file != null);
-			}
-		} catch (Throwable e) {
+			job.remove();
+		}
 
+		try {
+			file.delete(file.getCacheFileIfExists() != null);
+		} catch (TranscodeException e) {
 			Debug.out(e);
 		}
 	}
@@ -1415,14 +1432,9 @@ public class SBC_DevicesView
 			dropTarget = table.createDropTarget(DND.DROP_DEFAULT | DND.DROP_MOVE
 					| DND.DROP_COPY | DND.DROP_LINK | DND.DROP_TARGET_MOVE);
 			if (dropTarget != null) {
-				if (SWT.getVersion() >= 3107) {
-					dropTarget.setTransfer(new Transfer[] { HTMLTransfer.getInstance(),
-							URLTransfer.getInstance(), FileTransfer.getInstance(),
-							TextTransfer.getInstance() });
-				} else {
-					dropTarget.setTransfer(new Transfer[] { URLTransfer.getInstance(),
-							FileTransfer.getInstance(), TextTransfer.getInstance() });
-				}
+				dropTarget.setTransfer(new Transfer[] { HTMLTransfer.getInstance(),
+						URLTransfer.getInstance(), FileTransfer.getInstance(),
+						TextTransfer.getInstance() });
 
 				dropTarget.addDropListener(new DropTargetAdapter() {
 					public void dropAccept(DropTargetEvent event) {
diff --git a/com/aelitis/azureus/ui/swt/devices/TranscodeChooser.java b/com/aelitis/azureus/ui/swt/devices/TranscodeChooser.java
index d28e356..94b577f 100644
--- a/com/aelitis/azureus/ui/swt/devices/TranscodeChooser.java
+++ b/com/aelitis/azureus/ui/swt/devices/TranscodeChooser.java
@@ -34,6 +34,7 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
 import com.aelitis.azureus.core.devices.*;
 import com.aelitis.azureus.core.devices.Device;
@@ -276,8 +277,7 @@ public abstract class TranscodeChooser
 	private void createProfileList(SWTSkinObjectContainer soList,
 			String source) {
 		if (selectedTranscodeTarget == null && selectedDeviceTemplate == null) {
-			Utils.openMessageBox(Utils.findAnyShell(), SWT.OK, "No Device",
-					"No Device Selected!?");
+			new MessageBoxShell(SWT.OK, "No Device", "No Device Selected!?").open(null);
 			shell.dispose();
 			return;
 		}
@@ -302,8 +302,8 @@ public abstract class TranscodeChooser
 		}
 
 		if (transcodeProfiles.length == 0) {
-			Utils.openMessageBox(Utils.findAnyShell(), SWT.OK, "No Profiles",
-					"No Profiles for " + selectedTranscodeTarget.getDevice().getName());
+			new MessageBoxShell(SWT.OK, "No Profiles", "No Profiles for "
+					+ selectedTranscodeTarget.getDevice().getName()).open(null);
 			shell.dispose();
 			return;
 		}
@@ -784,11 +784,10 @@ public abstract class TranscodeChooser
 	 * @since 4.1.0.5
 	 */
 	private void noDevices() {
-		Utils.openMessageBox(
-				mainShell,
+		new MessageBoxShell(
 				SWT.OK,
 				"No Devices Found",
-				"We couldn't find any devices.  Maybe you didn't install the Vuze Transcoder Plugin?");
+				"We couldn't find any devices.  Maybe you didn't install the Vuze Transcoder Plugin?").open(null);
 		shell.dispose();
 	}
 
diff --git a/com/aelitis/azureus/ui/swt/devices/add/DeviceTemplateChooser.java b/com/aelitis/azureus/ui/swt/devices/add/DeviceTemplateChooser.java
index 944f98e..f35c164 100644
--- a/com/aelitis/azureus/ui/swt/devices/add/DeviceTemplateChooser.java
+++ b/com/aelitis/azureus/ui/swt/devices/add/DeviceTemplateChooser.java
@@ -29,6 +29,7 @@ import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
 import com.aelitis.azureus.core.devices.DeviceTemplate;
 import com.aelitis.azureus.core.devices.DeviceManager.DeviceManufacturer;
@@ -166,11 +167,10 @@ public class DeviceTemplateChooser
 	 * @since 4.1.0.5
 	 */
 	private void noDevices() {
-		Utils.openMessageBox(
-				null,
+		new MessageBoxShell(
 				SWT.OK,
 				"No Devices Found",
-				"We couldn't find any devices.  Maybe you didn't install the Vuze Transcoder Plugin?");
+				"We couldn't find any devices.  Maybe you didn't install the Vuze Transcoder Plugin?").open(null);
 		skinnedDialog.close();
 	}
 
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Completion.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Completion.java
new file mode 100644
index 0000000..b7173e8
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Completion.java
@@ -0,0 +1,194 @@
+/**
+ * Created on Feb 26, 2009
+ *
+ * Copyright 2008 Vuze, Inc.  All rights reserved.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
+ */
+ 
+package com.aelitis.azureus.ui.swt.devices.columns;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
+import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
+import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
+
+import com.aelitis.azureus.core.devices.DeviceOfflineDownload;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnImpl;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
+
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+/**
+ * @author TuxPaper
+ * @created Feb 26, 2009
+ *
+ */
+public class ColumnOD_Completion
+implements TableCellAddedListener, TableCellRefreshListener,
+TableCellDisposeListener, TableCellSWTPaintListener
+{
+	private static final int borderWidth = 1;
+
+	public static final String COLUMN_ID = "od_completion";
+
+	private static Font fontText;
+
+	private Map<TableCell,Integer> mapCellLastPercentDone = new HashMap<TableCell,Integer>();
+
+	private int marginHeight = -1;
+	
+	Color textColor;
+	
+
+	public ColumnOD_Completion(final TableColumn column) {
+		column.initialize(TableColumn.ALIGN_LEAD, TableColumn.POSITION_LAST, 145);
+		column.addListeners(this);
+		// cheat.  TODO: Either auto-add (in above method), or provide
+		// access via TableColumn instead of type casting
+		((TableColumnImpl)column).addCellOtherListener("SWTPaint", this);
+		column.setType(TableColumn.TYPE_GRAPHIC);
+		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
+	}
+
+	// @see org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener#cellAdded(org.gudy.azureus2.plugins.ui.tables.TableCell)
+	public void cellAdded(TableCell cell) {
+		if (marginHeight != -1) {
+			cell.setMarginHeight(marginHeight);
+		} else {
+			cell.setMarginHeight(2);
+		}
+	}
+
+	// @see org.gudy.azureus2.plugins.ui.tables.TableCellDisposeListener#dispose(org.gudy.azureus2.plugins.ui.tables.TableCell)
+	public void dispose(TableCell cell) {
+		mapCellLastPercentDone.remove(cell);
+	}
+
+	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
+	public void refresh(TableCell cell) {
+		DeviceOfflineDownload od =  (DeviceOfflineDownload) cell.getDataSource();
+
+		int percentDone = getPerThouDone(od);
+
+		Integer intObj = mapCellLastPercentDone.get(cell);
+		int lastPercentDone = intObj == null ? 0 : intObj.intValue();
+
+		if (!cell.setSortValue(percentDone) && cell.isValid()
+				&& lastPercentDone == percentDone) {
+			return;
+		}
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener#cellPaint(org.eclipse.swt.graphics.GC, org.gudy.azureus2.ui.swt.views.table.TableCellSWT)
+	public void cellPaint(GC gcImage, TableCellSWT cell) {
+		DeviceOfflineDownload od =  (DeviceOfflineDownload) cell.getDataSource();
+		
+		Rectangle bounds = cell.getBounds();
+
+		int yOfs = (bounds.height - 13) / 2 ;
+		int x1 = bounds.width - borderWidth - 2;
+		int y1 = bounds.height - 3 - yOfs;
+
+		if (x1 < 10 || y1 < 3) {
+			return;
+		}
+
+		if ( !od.isTransfering()){
+			
+			gcImage.fillRectangle( bounds );
+			
+			return;
+		}
+
+		int percentDone = getPerThouDone(od);
+
+		mapCellLastPercentDone.put(cell, new Integer(percentDone));
+		
+		ImageLoader imageLoader = ImageLoader.getInstance();
+		Image imgEnd = imageLoader.getImage("tc_bar_end");
+		Image img0 = imageLoader.getImage("tc_bar_0");
+		Image img1 = imageLoader.getImage("tc_bar_1");
+
+		//draw begining and end
+		if (!imgEnd.isDisposed()) {
+			gcImage.drawImage(imgEnd, bounds.x , bounds.y + yOfs);
+			gcImage.drawImage(imgEnd, bounds.x + x1 + 1, bounds.y + yOfs);
+		}
+		
+		
+		
+		int limit = (x1 * percentDone) / 1000;
+		
+		if (!img1.isDisposed() && limit > 0) {
+			Rectangle imgBounds = img1.getBounds();
+			gcImage.drawImage(img1, 0, 0, imgBounds.width, imgBounds.height,
+					bounds.x + 1, bounds.y + yOfs, limit, imgBounds.height);
+		}
+		if (percentDone < 1000 && !img0.isDisposed()) {
+			Rectangle imgBounds = img0.getBounds();
+			gcImage.drawImage(img0, 0, 0, imgBounds.width, imgBounds.height, bounds.x
+					+ limit + 1, bounds.y + yOfs, x1 - limit, imgBounds.height);
+		}
+
+		imageLoader.releaseImage("tc_bar_end");
+		imageLoader.releaseImage("tc_bar_0");
+		imageLoader.releaseImage("tc_bar_1");
+		
+		if(textColor == null) {
+			textColor = ColorCache.getColor(gcImage.getDevice(), "#006600" );
+		}
+
+		gcImage.setForeground(textColor);
+
+		if (fontText == null) {
+			fontText = Utils.getFontWithHeight(gcImage.getFont(), gcImage, 10);
+		}
+		
+		gcImage.setFont(fontText);
+		
+		String sText = DisplayFormatters.formatPercentFromThousands(percentDone);
+		
+		GCStringPrinter.printString(gcImage, sText, new Rectangle(bounds.x + 4,
+				bounds.y + yOfs, bounds.width - 4,13), true,
+				false, SWT.CENTER);
+	}
+
+	private int getPerThouDone(DeviceOfflineDownload od) {
+		if (od == null) {
+			return 0;
+		}
+		long total 	= od.getCurrentTransferSize();
+		long rem	= od.getRemaining();
+		
+		if ( total == 0 || total < rem ){
+			
+			return( 0 );
+		}
+		
+		if ( rem == 0 ){
+			
+			return( 1000 );
+		}
+		
+		return((int)( 1000 * ( total - rem ) / total ));
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Name.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Name.java
new file mode 100644
index 0000000..ce1394d
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Name.java
@@ -0,0 +1,58 @@
+/**
+ * Created on Feb 26, 2009
+ *
+ * Copyright 2008 Vuze, Inc.  All rights reserved.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
+ */
+
+package com.aelitis.azureus.ui.swt.devices.columns;
+
+
+import com.aelitis.azureus.core.devices.DeviceOfflineDownload;
+
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+/**
+ * @author TuxPaper
+ * @created Feb 26, 2009
+ *
+ */
+public class ColumnOD_Name
+	implements TableCellRefreshListener
+{
+	public static final String COLUMN_ID = "od_name";
+
+	public ColumnOD_Name(TableColumn column) {
+		column.initialize(TableColumn.ALIGN_LEAD, TableColumn.POSITION_LAST, 300);
+		column.addListeners(this);
+		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+	}
+
+	public void refresh(TableCell cell) {
+		DeviceOfflineDownload od = (DeviceOfflineDownload) cell.getDataSource();
+		if (od == null) {
+			return;
+		}
+
+		String text = od.getDownload().getName();
+		
+		if ( text == null || text.length() == 0 ){
+			
+			return;
+		}
+
+		cell.setText(text);
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Remaining.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Remaining.java
new file mode 100644
index 0000000..ff69a7e
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Remaining.java
@@ -0,0 +1,55 @@
+/**
+ * Created on Feb 26, 2009
+ *
+ * Copyright 2008 Vuze, Inc.  All rights reserved.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
+ */
+
+package com.aelitis.azureus.ui.swt.devices.columns;
+
+
+import com.aelitis.azureus.core.devices.DeviceOfflineDownload;
+
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+/**
+ * @author TuxPaper
+ * @created Feb 26, 2009
+ *
+ */
+public class ColumnOD_Remaining
+	implements TableCellRefreshListener
+{
+	public static final String COLUMN_ID = "od_remaining";
+	
+	public ColumnOD_Remaining(final TableColumn column) {
+		column.initialize(TableColumn.ALIGN_CENTER, TableColumn.POSITION_LAST, 80);
+		column.addListeners(this);
+		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+		
+	}
+
+	public void refresh(TableCell cell) {
+		DeviceOfflineDownload od = (DeviceOfflineDownload) cell.getDataSource();
+		if (od == null) {
+			return;
+		}
+
+		long remaining = od.getRemaining();
+		
+		cell.setText( remaining==0?"":DisplayFormatters.formatByteCountToKiBEtc( remaining ));
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Status.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Status.java
new file mode 100644
index 0000000..8cdb0cf
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Status.java
@@ -0,0 +1,79 @@
+/**
+ * Created on Feb 26, 2009
+ *
+ * Copyright 2008 Vuze, Inc.  All rights reserved.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
+ */
+
+package com.aelitis.azureus.ui.swt.devices.columns;
+
+
+import java.util.Locale;
+
+import com.aelitis.azureus.core.devices.DeviceOfflineDownload;
+
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.internat.MessageText.MessageTextListener;
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+/**
+ * @author TuxPaper
+ * @created Feb 26, 2009
+ *
+ */
+public class ColumnOD_Status
+	implements TableCellRefreshListener
+{
+	public static final String COLUMN_ID = "od_status";
+
+	private static final String[] js_resource_keys = {
+		"devices.od.idle",
+		"devices.od.xfering",
+	};
+
+	private static String[] js_resources = new String[js_resource_keys.length];
+	
+	public ColumnOD_Status(final TableColumn column) {
+		column.initialize(TableColumn.ALIGN_CENTER, TableColumn.POSITION_LAST, 80);
+		column.addListeners(this);
+		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+		
+		MessageText.addAndFireListener(new MessageTextListener() {
+			public void localeChanged(Locale old_locale, Locale new_locale) {
+				for (int i = 0; i < js_resources.length; i++) {
+					js_resources[i] = MessageText.getString(js_resource_keys[i]);
+				}
+								
+				column.invalidateCells();
+			}
+		});
+	}
+
+	public void refresh(TableCell cell) {
+		DeviceOfflineDownload od = (DeviceOfflineDownload) cell.getDataSource();
+		if (od == null) {
+			return;
+		}
+
+		String text = od.isTransfering()?js_resources[1]:js_resources[0];
+		
+		if ( text == null || text.length() == 0 ){
+			
+			return;
+		}
+
+		cell.setText(text);
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Completion.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Completion.java
index 59cee7d..eef8620 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Completion.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Completion.java
@@ -101,7 +101,7 @@ TableCellDisposeListener, TableCellSWTPaintListener
 	public void refresh(TableCell cell) {
 		TranscodeFile tf =  (TranscodeFile) cell.getDataSource();
 
-		int percentDone = getPercentDone(tf);
+		int percentDone = getPerThouDone(tf);
 
 		Integer intObj = (Integer) mapCellLastPercentDone.get(cell);
 		int lastPercentDone = intObj == null ? 0 : intObj.intValue();
@@ -116,7 +116,7 @@ TableCellDisposeListener, TableCellSWTPaintListener
 	public void cellPaint(GC gcImage, TableCellSWT cell) {
 		TranscodeFile tf =  (TranscodeFile) cell.getDataSource();
 
-		int percentDone = getPercentDone(tf) * 10;
+		int perThouDone = getPerThouDone(tf);
 
 		Rectangle bounds = cell.getBounds();
 
@@ -127,9 +127,8 @@ TableCellDisposeListener, TableCellSWTPaintListener
 		if (x1 < 10 || y1 < 3) {
 			return;
 		}
-		int textYofs = 0;
 
-		mapCellLastPercentDone.put(cell, new Integer(percentDone));
+		mapCellLastPercentDone.put(cell, new Integer(perThouDone));
 		
 		ImageLoader imageLoader = ImageLoader.getInstance();
 		Image imgEnd = imageLoader.getImage("tc_bar_end");
@@ -144,14 +143,14 @@ TableCellDisposeListener, TableCellSWTPaintListener
 		
 		
 		
-		int limit = (x1 * percentDone) / 1000;
+		int limit = (x1 * perThouDone) / 1000;
 		
 		if (!img1.isDisposed() && limit > 0) {
 			Rectangle imgBounds = img1.getBounds();
 			gcImage.drawImage(img1, 0, 0, imgBounds.width, imgBounds.height,
 					bounds.x + 1, bounds.y + yOfs, limit, imgBounds.height);
 		}
-		if (percentDone < 1000 && !img0.isDisposed()) {
+		if (perThouDone < 1000 && !img0.isDisposed()) {
 			Rectangle imgBounds = img0.getBounds();
 			gcImage.drawImage(img0, 0, 0, imgBounds.width, imgBounds.height, bounds.x
 					+ limit + 1, bounds.y + yOfs, x1 - limit, imgBounds.height);
@@ -175,15 +174,15 @@ TableCellDisposeListener, TableCellSWTPaintListener
 		
 		String sText;
 		
-		if ( tf != null && percentDone == 1000 && !tf.getTranscodeRequired()){
+		if ( tf != null && perThouDone == 1000 && !tf.getTranscodeRequired()){
 			
 			sText = na_text;
 			
 		}else{
 			
-			sText = DisplayFormatters.formatPercentFromThousands(percentDone);
+			sText = DisplayFormatters.formatPercentFromThousands(perThouDone);
 			
-			if ( tf != null && percentDone < 1000 ){
+			if ( tf != null && perThouDone < 1000 ){
 				
 				String eta = getETA(tf);
 			
@@ -199,15 +198,15 @@ TableCellDisposeListener, TableCellSWTPaintListener
 				false, SWT.CENTER);
 	}
 
-	private int getPercentDone(TranscodeFile tf) {
+	private int getPerThouDone(TranscodeFile tf) {
 		if (tf == null) {
 			return 0;
 		}
 		TranscodeJob job = tf.getJob();
 		if (job == null) {
-			return tf.isComplete()?100:0;
+			return tf.isComplete()?1000:0;
 		}
-		return job.getPercentComplete();
+		return job.getPercentComplete()*10;
 	}
 	
 	private String getETA(TranscodeFile tf) {
diff --git a/com/aelitis/azureus/ui/swt/imageloader/ImageLoader.java b/com/aelitis/azureus/ui/swt/imageloader/ImageLoader.java
index b2fe617..7ba23fa 100644
--- a/com/aelitis/azureus/ui/swt/imageloader/ImageLoader.java
+++ b/com/aelitis/azureus/ui/swt/imageloader/ImageLoader.java
@@ -86,6 +86,11 @@ public class ImageLoader
 
 	private int disabledOpacity;
 
+	private Set<String>		cached_resources = new HashSet<String>();
+	
+	private File cache_dir = new File(SystemProperties.getUserPath(), "cache" );
+	
+
 	public static ImageLoader getInstance() {
 		if (ImageLoader.instance == null) {
 			ImageLoader.instance = new ImageLoader(Display.getDefault(), null);
@@ -101,6 +106,18 @@ public class ImageLoader
 	public ImageLoader(/*ClassLoader classLoader,*/Display display,
 			SkinProperties skinProperties) {
 		//this.classLoader = classLoader;
+		
+		File[]	files = cache_dir.listFiles();
+		
+		if ( files != null ){
+			for (File f: files ){
+				String	name = f.getName();
+				if ( name.endsWith( ".ico" )){
+					cached_resources.add( name );
+				}
+			}
+		}
+		
 		mapImages = new ConcurrentHashMap<String, ImageLoaderRefInfo>();
 		notFound = new ArrayList<String>();
 		this.display = display;
@@ -434,33 +451,37 @@ public class ImageLoader
 			images = findResources(sKey);
 
 			if (images == null) {
-				final File cache = new File(SystemProperties.getUserPath(), "cache"
-						+ File.separator + sKey.hashCode() + ".ico");
-				if (cache.exists()) {
-					try {
-						FileInputStream fis = new FileInputStream(cache);
-
+				String	cache_key = sKey.hashCode() + ".ico";
+				if ( cached_resources.contains( cache_key )){
+					File cache = new File( cache_dir, cache_key );
+					if (cache.exists()) {
 						try {
-							byte[] imageBytes = FileUtil.readInputStreamAsByteArray(fis);
-							InputStream is = new ByteArrayInputStream(imageBytes);
-
-							org.eclipse.swt.graphics.ImageLoader swtImageLoader = new org.eclipse.swt.graphics.ImageLoader();
-							ImageData[] imageDatas = swtImageLoader.load(is);
-							images = new Image[imageDatas.length];
-							for (int i = 0; i < imageDatas.length; i++) {
-								images[i] = new Image(Display.getCurrent(), imageDatas[i]);
-							}
-
+							FileInputStream fis = new FileInputStream(cache);
+	
 							try {
-								is.close();
-							} catch (IOException e) {
+								byte[] imageBytes = FileUtil.readInputStreamAsByteArray(fis);
+								InputStream is = new ByteArrayInputStream(imageBytes);
+	
+								org.eclipse.swt.graphics.ImageLoader swtImageLoader = new org.eclipse.swt.graphics.ImageLoader();
+								ImageData[] imageDatas = swtImageLoader.load(is);
+								images = new Image[imageDatas.length];
+								for (int i = 0; i < imageDatas.length; i++) {
+									images[i] = new Image(Display.getCurrent(), imageDatas[i]);
+								}
+	
+								try {
+									is.close();
+								} catch (IOException e) {
+								}
+							} finally {
+								fis.close();
 							}
-						} finally {
-							fis.close();
+						} catch (Throwable e) {
+							Debug.printStackTrace(e);
 						}
-					} catch (Throwable e) {
-						Debug.printStackTrace(e);
 					}
+				}else{
+					cached_resources.remove( cache_key );
 				}
 
 				if (images == null) {
@@ -618,28 +639,36 @@ public class ImageLoader
 			return image;
 		}
 
-		final File cache = new File(SystemProperties.getUserPath(), "cache"
-				+ File.separator + url.hashCode() + ".ico");
-		if (cache.exists()) {
-			try {
-				FileInputStream fis = new FileInputStream(cache);
+		final String cache_key = url.hashCode() + ".ico";
+		
+		final File cache_file = new File( cache_dir, cache_key );
 
+		if ( cached_resources.contains( cache_key )){
+			
+			if ( cache_file.exists()){
 				try {
-					byte[] imageBytes = FileUtil.readInputStreamAsByteArray(fis);
-					InputStream is = new ByteArrayInputStream(imageBytes);
-					Image image = new Image(Display.getCurrent(), is);
+					FileInputStream fis = new FileInputStream(cache_file);
+	
 					try {
-						is.close();
-					} catch (IOException e) {
+						byte[] imageBytes = FileUtil.readInputStreamAsByteArray(fis);
+						InputStream is = new ByteArrayInputStream(imageBytes);
+						Image image = new Image(Display.getCurrent(), is);
+						try {
+							is.close();
+						} catch (IOException e) {
+						}
+						mapImages.put(url, new ImageLoaderRefInfo(image));
+						l.imageDownloaded(image, true);
+						return image;
+					} finally {
+						fis.close();
 					}
-					mapImages.put(url, new ImageLoaderRefInfo(image));
-					l.imageDownloaded(image, true);
-					return image;
-				} finally {
-					fis.close();
+				} catch (Throwable e) {
+					Debug.printStackTrace(e);
 				}
-			} catch (Throwable e) {
-				Debug.printStackTrace(e);
+			}else{
+				
+				cached_resources.remove( cache_key );
 			}
 		}
 
@@ -648,7 +677,8 @@ public class ImageLoader
 					public void imageDownloaded(final byte[] imageBytes) {
 						Utils.execSWTThread(new AERunnable() {
 							public void runSupport() {
-								FileUtil.writeBytesAsFile(cache.getAbsolutePath(), imageBytes);
+								FileUtil.writeBytesAsFile(cache_file.getAbsolutePath(), imageBytes);
+								cached_resources.add( cache_key );
 								InputStream is = new ByteArrayInputStream(imageBytes);
 								Image image = new Image(Display.getCurrent(), is);
 								try {
diff --git a/com/aelitis/azureus/ui/swt/shells/BrowserWindow.java b/com/aelitis/azureus/ui/swt/shells/BrowserWindow.java
index d538ef8..db58364 100644
--- a/com/aelitis/azureus/ui/swt/shells/BrowserWindow.java
+++ b/com/aelitis/azureus/ui/swt/shells/BrowserWindow.java
@@ -22,8 +22,7 @@ package com.aelitis.azureus.ui.swt.shells;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.*;
-import org.eclipse.swt.events.TraverseEvent;
-import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.events.*;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.widgets.*;
@@ -117,14 +116,7 @@ public class BrowserWindow
 		});
 
 
-		browser = null;
-		
-		try {
-			browser = new Browser(shell, Utils.getInitialBrowserStyle(SWT.NONE));
-		} catch (Throwable t) {
-			shell.dispose();
-			return;
-		}
+		browser = Utils.createSafeBrowser(shell, SWT.NONE);
 		
 		if (browser == null) {
 			shell.dispose();
@@ -140,6 +132,9 @@ public class BrowserWindow
 
 		browser.addProgressListener(new ProgressListener() {
 			public void completed(ProgressEvent event) {
+				if (browser.isDisposed() || browser.getShell().isDisposed()) {
+					return;
+				}
 				shell.open();
 			}
 
@@ -149,6 +144,9 @@ public class BrowserWindow
 
 		browser.addCloseWindowListener(new CloseWindowListener() {
 			public void close(WindowEvent event) {
+				if (browser.isDisposed() || browser.getShell().isDisposed()) {
+					return;
+				}
 				context.debug("window.close called");
 				shell.dispose();
 			}
@@ -157,6 +155,9 @@ public class BrowserWindow
 		browser.addTitleListener(new TitleListener() {
 
 			public void changed(TitleEvent event) {
+				if (browser.isDisposed() || browser.getShell().isDisposed()) {
+					return;
+				}
 				shell.setText(event.title);
 			}
 
@@ -164,6 +165,9 @@ public class BrowserWindow
 		
 		browser.addStatusTextListener(new StatusTextListener() {
 			public void changed(StatusTextEvent event) {
+				if (browser.isDisposed() || browser.getShell().isDisposed()) {
+					return;
+				}
 				if(MessageBoxShell.STATUS_TEXT_CLOSE.equals(event.text)) {
 					//For some reason disposing the shell / browser in the same Thread makes
 					//ieframe.dll crash on windows.
diff --git a/com/aelitis/azureus/ui/swt/shells/LightBoxBrowserWindow.java b/com/aelitis/azureus/ui/swt/shells/LightBoxBrowserWindow.java
deleted file mode 100644
index 8cf3d7e..0000000
--- a/com/aelitis/azureus/ui/swt/shells/LightBoxBrowserWindow.java
+++ /dev/null
@@ -1,530 +0,0 @@
-package com.aelitis.azureus.ui.swt.shells;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.*;
-import org.eclipse.swt.custom.StackLayout;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.ui.swt.Messages;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.components.shell.LightBoxShell;
-import org.gudy.azureus2.ui.swt.components.shell.StyledShell;
-import org.gudy.azureus2.ui.swt.components.widgets.BubbleButton;
-import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-
-import com.aelitis.azureus.core.messenger.ClientMessageContext;
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.browser.BrowserContext;
-import com.aelitis.azureus.ui.swt.browser.listener.ConfigListener;
-import com.aelitis.azureus.ui.swt.browser.listener.DisplayListener;
-import com.aelitis.azureus.ui.swt.browser.listener.LightBoxBrowserListener;
-import com.aelitis.azureus.util.ConstantsVuze;
-
-/**
- * A window with the lightbox effect hosting a browser widget in a stylized shell
- * 
- * @author knguyen
- *
- */
-public class LightBoxBrowserWindow
-{
-	private static boolean CUSTOM_TRIM = true;
-
-	private static boolean DIM = false;
-
-	private String url = null;
-
-	private String pageVerifierValue = ConstantsVuze.URL_PAGE_VERIFIER_VALUE;
-
-	private StackLayout stack = new StackLayout();
-
-	private Composite errorPanel;
-
-	private Composite contentPanel;
-
-	private Browser browser;
-
-	private StyledShell styledShell;
-
-	private LightBoxShell lightBoxShell;
-
-	private int browserWidth = 0;
-
-	private int browserHeight = 0;
-
-	private Label errorMessageLabel;
-
-	private String redirectURL = null;
-
-	private Color borderColor = null;
-
-	private Color contentBackgroundColor = null;
-
-	private UIFunctionsSWT uiFunctions;
-
-	private closeListener closeListener;
-
-	private String callback;
-
-	private ClientMessageContext callBackContext;
-
-	private Composite waitPanel;
-
-	private Label waitMessageLabel;
-
-	public LightBoxBrowserWindow(String url, String prefixVerifier, int width,
-			int height) {
-		this.url = url;
-		this.pageVerifierValue = prefixVerifier;
-		browserWidth = width;
-		browserHeight = height;
-
-		Utils.execSWTThread(new Runnable() {
-			public void run() {
-				init();
-			}
-		});
-
-	}
-
-	public LightBoxBrowserWindow(String url, int width, int height) {
-		this(url, null, width, height);
-	}
-
-	public LightBoxBrowserWindow(String url) {
-		this(url, null, 0, 0);
-	}
-
-	public void init() {
-		uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-		if (null == uiFunctions) {
-			throw new IllegalStateException(
-					"No instance of UIFunctionsSWT found; the UIFunctionsManager might not have been initialized properly");
-		}
-
-		lightBoxShell = new LightBoxShell(true);
-		//Shell mainShell = uiFunctions.getMainShell();
-		
-		borderColor = new Color(lightBoxShell.getDisplay(), 38, 38, 38);
-		contentBackgroundColor = new Color(lightBoxShell.getDisplay(), 13, 13, 13);
-
-		/*
-		 * Create the StyledShell to host the browser
-		 */
-		styledShell = lightBoxShell.createPopUpShell(6, true, CUSTOM_TRIM);
-
-		styledShell.setBackground(borderColor);
-
-		styledShell.addListener(SWT.Traverse, new Listener() {
-			public void handleEvent(Event e) {
-				if (e.detail == SWT.TRAVERSE_ESCAPE) {
-					e.doit = false;
-					close();
-				}
-			}
-		});
-		
-		final Listener escListener = new Listener() {
-			public void handleEvent(Event event) {
-				if (event.keyCode == 27) {
-					close();
-				}
-			}
-		};
-		styledShell.getShell().getDisplay().addFilter(SWT.KeyDown, escListener);
-		styledShell.addListener(SWT.Dispose, new Listener() {
-			public void handleEvent(Event event) {
-				event.display.removeFilter(SWT.KeyDown, escListener);
-			}
-		});
-		
-		
-		/*
-		 * Use a StackLayout with an error panel in the background so we can switch it to the front
-		 * when an error has occurred
-		 */
-		contentPanel = styledShell.getContent();
-		stack.marginHeight = 0;
-		stack.marginWidth = 0;
-		contentPanel.setLayout(stack);
-		contentPanel.setBackground(contentBackgroundColor);
-
-		if (CUSTOM_TRIM) {
-  		waitPanel = new Composite(contentPanel, SWT.NONE);
-  		waitPanel.setBackground(contentBackgroundColor);
-  		waitPanel.setLayout(new FormLayout());
-  		waitPanel.setBackgroundMode(SWT.INHERIT_DEFAULT);
-  		waitMessageLabel = new Label(waitPanel, SWT.CENTER);
-  		waitMessageLabel.setBackground(waitPanel.getBackground());
-  		waitMessageLabel.setForeground(Colors.grey);
-  		waitMessageLabel.setLayoutData(Utils.getFilledFormData());
-  		Messages.setLanguageText(waitMessageLabel, "v3.MainWindow.Loading");
-		} else {
-			contentPanel.getShell().setText(MessageText.getString("v3.MainWindow.Loading"));
-		}
-
-		
-		errorPanel = new Composite(contentPanel, SWT.NONE);
-		errorPanel.setBackground(contentBackgroundColor);
-		errorPanel.setLayout(new FormLayout());
-		errorPanel.setBackgroundMode(SWT.INHERIT_DEFAULT);
-		errorMessageLabel = new Label(errorPanel, SWT.WRAP);
-		errorMessageLabel.setBackground(errorPanel.getBackground());
-		errorMessageLabel.setForeground(Colors.grey);
-
-		BubbleButton closeButton = new BubbleButton(errorPanel);
-		closeButton.setText(MessageText.getString("wizard.close"));
-		FormData fData = new FormData();
-		fData.width = 100;
-		fData.bottom = new FormAttachment(100, -20);
-		fData.right = new FormAttachment(100, -20);
-		
-		
-		closeButton.setLayoutData(fData);
-
-		fData = new FormData();
-		fData.top = new FormAttachment(0, 0);
-		fData.left = new FormAttachment(0, 0);
-		fData.bottom = new FormAttachment(closeButton, 0);
-		fData.right = new FormAttachment(100, -20);
-
-		errorMessageLabel.setLayoutData(fData);
-
-		/*
-		 * This close button is only on the error panel
-		 */
-		closeButton.addMouseListener(new MouseAdapter() {
-
-			public void mouseDown(MouseEvent e) {
-				close();
-			}
-
-		});
-		//		closeButton.addSelectionListener(new SelectionListener() {
-		//			public void widgetSelected(SelectionEvent e) {
-		//				widgetDefaultSelected(e);
-		//			}
-		//
-		//			public void widgetDefaultSelected(SelectionEvent e) {
-		//				close();
-		//			}
-		//
-		//		});
-
-		/*
-		 * Disposing resources when the LightBoxShell is disposed
-		 */
-		lightBoxShell.addDisposeListener(new DisposeListener() {
-			public void widgetDisposed(DisposeEvent e) {
-				if (null != borderColor && false == borderColor.isDisposed()) {
-					borderColor.dispose();
-				}
-				if (null != contentBackgroundColor
-						&& false == contentBackgroundColor.isDisposed()) {
-					contentBackgroundColor.dispose();
-				}
-			}
-
-		});
-
-		/*
-		 * The Browser widget is very platform-dependent and can only support a limited set
-		 * of native browsers; if a platform is not supported or no compatible native browser
-		 * is found then the browser will throw an exception.
-		 * 
-		 * If we can not instantiate a browser we will still bring up the window but show an
-		 * error panel instead of the browser
-		 * 
-		 */
-		try {
-			browser = new Browser(contentPanel,
-					Utils.getInitialBrowserStyle(SWT.NONE));
-		} catch (Throwable t) {
-			// Be silent if no browser
-		}
-
-		if (browserWidth > 0 && browserHeight > 0) {
-			styledShell.setSize(browserWidth, browserHeight,
-					StyledShell.HINT_ALIGN_CENTER | StyledShell.HINT_ALIGN_CENTER);
-		}
-
-		contentPanel.layout();
-
-		/*
-		 * Make sure the main shell is not minimized when the lightbox is opened
-		 */
-		if (true == uiFunctions.getMainShell().getMinimized()) {
-			uiFunctions.getMainShell().setMinimized(false);
-		}
-		
-		if (CUSTOM_TRIM) {
-  		stack.topControl = waitPanel;
-  		Point computeSize = waitPanel.computeSize(browserWidth > 0 ? browserWidth : 400, 0);
-  		Point size = styledShell.getShell().computeSize(computeSize.x, computeSize.y);
-  		styledShell.setSize(size.x, size.y + 15);
-  		styledShell.centersShell();
-		} else {
-  		styledShell.setSize(browserWidth > 0 ? browserWidth : 400, 0);
-  		styledShell.centersShell();
-		}
-
-
-		styledShell.hideShell(true);
-		Utils.execSWTThreadLater(1000, new AERunnable() {
-			public void runSupport() {
-				if (!styledShell.getShell().isDisposed()) {
-					styledShell.hideShell(false);
-				}
-			}
-		});
-		lightBoxShell.open(styledShell, DIM);
-
-		if (null != browser) {
-			hookListeners();
-			setUrl(url);
-			stack.topControl = browser;
-		} else {
-			stack.topControl = errorPanel;
-		}
-	}
-
-	private void hookListeners() {
-
-		/*
-		 * If a java script 'window.close' message is detected from the loaded page
-		 * then close the lightbox
-		 */
-		browser.addCloseWindowListener(new CloseWindowListener() {
-			public void close(WindowEvent event) {
-				LightBoxBrowserWindow.this.close();
-			}
-		});
-		
-		browser.addLocationListener(new LocationListener() {
-		
-			public void changing(LocationEvent event) {
-				lightBoxShell.showBusy(true, 500);
-			}
-		
-			public void changed(LocationEvent event) {
-				// TODO Auto-generated method stub
-		
-			}
-		});
-
-		/*
-		 * Once a page has finished loading make sure again that the main shell is not minimized
-		 * then fade the styledShell back into being visible
-		 */
-		browser.addProgressListener(new ProgressListener() {
-			public void completed(ProgressEvent event) {
-
-				/*
-				 * If a prefixVerifier is specified then verify the loaded page
-				 */
-				if (null != pageVerifierValue) {
-
-					String browserText = null;
-
-					try {
-						browserText = browser.getText();
-					} catch (Throwable t) {
-						/*
-						 * KN: Do nothing for verification if Browser.getText() is not found;
-						 * this could be due the the SWT jar being of an older version
-						 */
-					}
-					if (null != browserText && false == isPageVerified(browser.getText())) {
-
-						String errorMessage = MessageText.getString("Browser.popup.error.no.access");
-						errorMessageLabel.setText(errorMessage);
-						if (false == stack.topControl.equals(errorPanel)) {
-							stack.topControl = errorPanel;
-							setSize(300, 200);
-							contentPanel.layout();
-						}
-					}
-				}
-
-				/*
-				 * Once a page has finished loading make sure the main shell is not minimized
-				 * then fade the styledShell back into being visible
-				 */
-				if (true == uiFunctions.getMainShell().getMinimized()) {
-					uiFunctions.getMainShell().setMinimized(false);
-				}
-
-				lightBoxShell.showBusy(false, 0);
-				//styledShell.animateFade(100);
-				if (browserWidth > 0 && browserHeight > 0) {
-					styledShell.setSize(browserWidth, browserHeight,
-							StyledShell.HINT_ALIGN_CENTER | StyledShell.HINT_ALIGN_CENTER);
-				}
-				styledShell.hideShell(false);
-			}
-
-			public void changed(ProgressEvent event) {
-				/*
-				 * When ever the URL changes hide the shell to eliminate flickering then
-				 * show it again once the page has finished loading
-				 */
-				if (event.current == 0 && event.total != 0) {
-					//styledShell.hideShell(true);
-					lightBoxShell.showBusy(true, 500);
-				}
-			}
-		});
-
-		/*
-		 * If not using custom trim for the shell then we must display the title since the standard
-		 * dialog trim has the title bar
-		 */
-		if (false == styledShell.isUseCustomTrim()) {
-			browser.addTitleListener(new TitleListener() {
-
-				public void changed(TitleEvent event) {
-					styledShell.setText(event.title);
-
-				}
-
-			});
-		}
-		/*
-		 * Add the appropriate messaging listeners
-		 */
-		final ClientMessageContext context = new BrowserContext(
-				"lightbox-browser-window" + Math.random(), browser, null, true);
-
-		/*
-		 * This listener is for when the loaded page is requesting some info
-		 */
-		context.addMessageListener(new ConfigListener(browser));
-
-		/*
-		 * This listener will respond to actions that effects this window such as 'close', 'resize', etc...
-		 */
-		context.addMessageListener(new LightBoxBrowserListener(this) {
-			public void handleMessage(BrowserMessage message) {
-				super.handleMessage(message);
-				String opID = message.getOperationId();
-				decodedMap = message.getDecodedMap();
-				if (true == OP_INVOKE_CALLBACK.equals(opID) && callBackContext != null && callback != null) { 
-					callBackContext.executeInBrowser(callback);
-				}
-			}
-		});
-
-		/*
-		 * This listener handles a number of tasks involving opening external browser,
-		 * popping up traditional browser dialogs, and navigating to embedded browser
-		 * pages in the client application
-		 */
-		context.addMessageListener(new DisplayListener(null));
-
-	}
-
-	/**
-	 * Returns whether the given block of html contains the predefined '<INPUT...' block
-	 * This is used to detect whether the url given was resolved and loaded properly, or
-	 * whether an error may have prevented the page from loading fully.
-	 * 
-	 * NOTE: This is not a security implementation and no reliance should be made that
-	 * this check is enough to prevent spoofing, etc...
-	 * 
-	 * @param html
-	 * @return
-	 */
-	private boolean isPageVerified(String html) {
-		if (null == html || html.length() < 1) {
-			return false;
-		}
-
-		//		String fullSearchString = "<INPUT type=hidden value=" + pageVerifierValue
-		//				+ " name=pageVerifier>";
-
-		//TODO: WARNING!!!!! this has been temporarily hardcoded
-		if (html.indexOf("vuzePage") != -1) {
-			return true;
-		}
-		return false;
-	}
-
-	public void close() {
-		lightBoxShell.close();
-		if (closeListener != null) {
-			closeListener.close();
-		}
-	}
-
-	public void refresh() {
-		if (null != browser) {
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					browser.refresh();
-				}
-			});
-		}
-	}
-
-	public void setUrl(String url) {
-		if (null != browser) {
-			browser.setUrl(url);
-			browser.setData("StartURL", url);
-		}
-	}
-
-	public void setSize(int width, int height) {
-		browserWidth = width;
-		browserHeight = height;
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				styledShell.getShell().setRedraw(false);
-				styledShell.setSize(browserWidth, browserHeight);
-				styledShell.centersShell();
-				styledShell.getShell().setRedraw(true);
-			}
-		});
-
-	}
-
-	public String getRedirectURL() {
-		return redirectURL;
-	}
-
-	public void setRedirectURL(String redirectURL) {
-		this.redirectURL = redirectURL;
-	}
-
-	public void setCloseListener(closeListener l) {
-		closeListener = l;
-	}
-
-	public interface closeListener
-	{
-		public void close();
-	}
-
-	/**
-	 * @param callback
-	 * @param clientMessageContext 
-	 *
-	 * @since 4.0.0.5
-	 */
-	public void setCallback(String callback, ClientMessageContext clientMessageContext) {
-		this.callback = callback;
-		this.callBackContext = clientMessageContext;
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/shells/MessageWindow.java b/com/aelitis/azureus/ui/swt/shells/MessageWindow.java
deleted file mode 100644
index eec6092..0000000
--- a/com/aelitis/azureus/ui/swt/shells/MessageWindow.java
+++ /dev/null
@@ -1,271 +0,0 @@
-package com.aelitis.azureus.ui.swt.shells;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.StyleRange;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.ui.swt.ITwistieListener;
-import org.gudy.azureus2.ui.swt.TwistieLabel;
-import org.gudy.azureus2.ui.swt.TwistieSection;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
-import org.gudy.azureus2.ui.swt.components.shell.StyledShell;
-import org.gudy.azureus2.ui.swt.components.widgets.BubbleButton;
-import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.progress.ProgressReportMessage;
-
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-
-public class MessageWindow
-{
-	private Label messageLabel = null;
-
-	private String message = null;
-
-	/**
-	 * A List of <code>IMessage</code>
-	 */
-	private List detailMessages = null;
-
-	private Button closeButton = null;
-
-	private StyledText detailListWidget;
-
-	private TwistieSection detailTwistie;
-
-	private Label titleLabel = null;
-
-	private String title = null;
-
-	private Color errorColor;
-
-	private Shell shell;
-	private Composite content;
-	
-	public MessageWindow(Shell parentShell, int borderWidth) {
-		shell = ShellFactory.createShell(parentShell, SWT.DIALOG_TRIM);
-		FillLayout fillLayout = new FillLayout();
-		fillLayout.marginHeight = 0;
-		fillLayout.marginWidth = 0;
-		shell.setLayout(fillLayout);
-
-		if (true == Constants.isOSX) {
-			UIFunctionsManagerSWT.getUIFunctionsSWT().createMainMenu(shell);
-		}
-		Utils.setShellIcon(shell);
-
-		content = new Composite(shell, SWT.DOUBLE_BUFFERED);
-		content.setBackgroundMode(SWT.INHERIT_DEFAULT);
-
-		createControls(content);
-	}
-
-
-	private void createControls(Composite parent) {
-		errorColor = Colors.colorError;
-
-		//setBackground(ColorCache.getColor(parent.getDisplay(), 38, 38, 38));
-		//parent.setBackground(ColorCache.getColor(parent.getDisplay(), 13, 13, 13));
-		parent.setLayout(new FormLayout());
-		parent.setBackgroundMode(SWT.INHERIT_FORCE);
-
-		titleLabel = new Label(parent, SWT.NONE);
-		Utils.setFontHeight(titleLabel, 12, SWT.NORMAL);
-		//titleLabel.setForeground(ColorCache.getColor(parent.getDisplay(), 206, 206,
-		//		206));
-
-		FormData titleLabelData = new FormData();
-		titleLabelData.top = new FormAttachment(0, 6);
-		titleLabelData.left = new FormAttachment(0, 6);
-		titleLabel.setLayoutData(titleLabelData);
-
-		messageLabel = new Label(parent, SWT.WRAP);
-		//messageLabel.setForeground(ColorCache.getColor(parent.getDisplay(), 206,
-		//		206, 206));
-
-		FormData messageLabelData = new FormData();
-		messageLabelData.top = new FormAttachment(titleLabel, 20);
-		messageLabelData.left = new FormAttachment(0, 20);
-		messageLabelData.width = 300;
-		messageLabel.setLayoutData(messageLabelData);
-
-		closeButton = new Button(parent,SWT.PUSH);
-		FormData closeButtonData = new FormData();
-		closeButtonData.right = new FormAttachment(100, -20);
-		closeButtonData.bottom = new FormAttachment(100, -20);
-		closeButtonData.width = 80;
-		closeButton.setLayoutData(closeButtonData);
-		closeButton.setText("Close");
-		closeButton.addMouseListener(new MouseAdapter() {
-			public void mouseUp(MouseEvent e) {
-				close();
-			}
-		});
-
-		detailTwistie = new TwistieSection(parent, TwistieLabel.SHOW_SEPARATOR);
-
-		detailTwistie.setVisible(false);
-
-		FormData detailTwistieData = new FormData();
-		detailTwistieData.left = new FormAttachment(0, 20);
-		detailTwistieData.right = new FormAttachment(100, -20);
-		detailTwistieData.top = new FormAttachment(messageLabel, 20);
-		detailTwistieData.bottom = new FormAttachment(closeButton, -20);
-		detailTwistie.setLayoutData(detailTwistieData);
-
-		detailTwistie.setTitle("Detail:");
-
-		Composite sectionContent = detailTwistie.getContent();
-		//detailTwistie.setForeground(ColorCache.getColor(parent.getDisplay(), 206,
-		//		206, 206));
-		//		detailTwistie.setBackground(ColorCache.getColor(parent.getDisplay(),
-		//				13, 13, 13));
-
-		sectionContent.setLayout(new FormLayout());
-		detailListWidget = new StyledText(sectionContent, SWT.V_SCROLL | SWT.WRAP);
-		detailListWidget.setEditable(false);
-
-		FormData detailListWidgetData = new FormData();
-		detailListWidgetData.left = new FormAttachment(0, 0);
-		detailListWidgetData.right = new FormAttachment(100, 0);
-		detailListWidgetData.top = new FormAttachment(0, 0);
-		detailListWidgetData.bottom = new FormAttachment(100, 0);
-		detailListWidgetData.height = 100;
-		detailListWidgetData.width = 300;
-		detailListWidget.setLayoutData(detailListWidgetData);
-
-		//detailListWidget.setBackground(ColorCache.getColor(parent.getDisplay(),
-		//		255, 255, 230));
-
-		detailTwistie.addTwistieListener(new ITwistieListener() {
-
-			public void isCollapsed(boolean value) {
-				if (null != shell && false == shell.isDisposed()) {
-					shell.pack(true);
-				}
-			}
-		});
-
-	}
-
-	public void open() {
-		messageLabel.setText(message != null ? message : "");
-		messageLabel.setSize(messageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
-
-		if (null != title) {
-			titleLabel.setText(title);
-		}
-		if (null != detailMessages && false == detailMessages.isEmpty()) {
-			boolean hasError = false;
-			for (Iterator iterator = detailMessages.iterator(); iterator.hasNext();) {
-				Object obj = (Object) iterator.next();
-				if (obj instanceof ProgressReportMessage) {
-					ProgressReportMessage message = (ProgressReportMessage) obj;
-
-					if (false == hasError && true == message.isError()) {
-						hasError = true;
-					}
-					appendToDetail(message.getValue(), message.isError());
-				}
-
-			}
-
-			detailTwistie.setVisible(hasError);
-		} else {
-			detailListWidget.setText("");
-			detailTwistie.setVisible(false);
-		}
-		shell.pack(true);
-		shell.open();
-	}
-
-	public boolean isAlive() {
-		if (null == shell || true == shell.isDisposed()) {
-			return false;
-		}
-		return true;
-	}
-	
-	public void setSize(int width, int height) {
-		shell.setSize(width,height);
-	}
-	
-	public void close() {
-		if (true == isAlive()) {
-			shell.close();
-		}
-	}
-	
-	
-	
-	/**
-	 * Appends the given message to the detail panel; render the message in error color if specified
-	 * @param value
-	 * @param isError if <code>true</code> then render the message in the system error color; otherwise render in default color
-	 */
-	private void appendToDetail(String value, boolean isError) {
-
-		if (null == value || value.length() < 1) {
-			return;
-		}
-
-		if (null == detailListWidget || detailListWidget.isDisposed()) {
-			return;
-		}
-
-		int charCount = detailListWidget.getCharCount();
-		detailListWidget.append(value + "\n");
-		if (true == isError) {
-			StyleRange style2 = new StyleRange();
-			style2.start = charCount;
-			style2.length = value.length();
-			style2.foreground = errorColor;
-			detailListWidget.setStyleRange(style2);
-		}
-
-	}
-
-	public String getMessage() {
-		return message;
-	}
-
-	public void setMessage(String successMessage) {
-		this.message = successMessage;
-	}
-
-	public List getDetailMessages() {
-		return detailMessages;
-	}
-
-	public void setDetailMessages(List detailMessages) {
-		this.detailMessages = detailMessages;
-	}
-
-	public String getTitle() {
-		return title;
-	}
-
-	public void setTitle(String title) {
-		this.title = title;
-	}
-	
-	public Shell getShell() {
-		return shell;
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/shells/StyledMessageWindow.java b/com/aelitis/azureus/ui/swt/shells/StyledMessageWindow.java
deleted file mode 100644
index b94062d..0000000
--- a/com/aelitis/azureus/ui/swt/shells/StyledMessageWindow.java
+++ /dev/null
@@ -1,233 +0,0 @@
-package com.aelitis.azureus.ui.swt.shells;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.StyleRange;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.gudy.azureus2.ui.swt.ITwistieListener;
-import org.gudy.azureus2.ui.swt.TwistieLabel;
-import org.gudy.azureus2.ui.swt.TwistieSection;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.components.shell.StyledShell;
-import org.gudy.azureus2.ui.swt.components.widgets.BubbleButton;
-import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.progress.ProgressReportMessage;
-
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-
-public class StyledMessageWindow
-	extends StyledShell
-{
-	private Label messageLabel = null;
-
-	private String message = null;
-
-	/**
-	 * A List of <code>IMessage</code>
-	 */
-	private List detailMessages = null;
-
-	private BubbleButton closeButton = null;
-
-	private StyledText detailListWidget;
-
-	private TwistieSection detailTwistie;
-
-	private Label titleLabel = null;
-
-	private String title = null;
-
-	private Color errorColor;
-
-	public StyledMessageWindow(Shell parentShell, int borderWidth) {
-		super(parentShell, borderWidth);
-		createControls(getContent());
-	}
-
-	public StyledMessageWindow(Shell parentShell, int borderWidth,
-			boolean useCustomTrim) {
-		super(parentShell, borderWidth, useCustomTrim);
-
-		createControls(getContent());
-	}
-
-	private void createControls(Composite parent) {
-		errorColor = Colors.colorError;
-
-		setBackground(ColorCache.getColor(parent.getDisplay(), 38, 38, 38));
-		parent.setBackground(ColorCache.getColor(parent.getDisplay(), 13, 13, 13));
-		parent.setLayout(new FormLayout());
-		parent.setBackgroundMode(SWT.INHERIT_FORCE);
-
-		titleLabel = new Label(parent, SWT.NONE);
-		Utils.setFontHeight(titleLabel, 12, SWT.NORMAL);
-		titleLabel.setForeground(ColorCache.getColor(parent.getDisplay(), 206, 206,
-				206));
-
-		FormData titleLabelData = new FormData();
-		titleLabelData.top = new FormAttachment(0, 6);
-		titleLabelData.left = new FormAttachment(0, 6);
-		titleLabel.setLayoutData(titleLabelData);
-
-		messageLabel = new Label(parent, SWT.WRAP);
-		messageLabel.setForeground(ColorCache.getColor(parent.getDisplay(), 206,
-				206, 206));
-
-		FormData messageLabelData = new FormData();
-		messageLabelData.top = new FormAttachment(titleLabel, 20);
-		messageLabelData.left = new FormAttachment(0, 20);
-		messageLabelData.width = 300;
-		messageLabel.setLayoutData(messageLabelData);
-
-		closeButton = new BubbleButton(parent);
-		FormData closeButtonData = new FormData();
-		closeButtonData.right = new FormAttachment(100, -20);
-		closeButtonData.bottom = new FormAttachment(100, -20);
-		closeButton.setLayoutData(closeButtonData);
-		closeButton.setText("Close");
-		closeButton.addMouseListener(new MouseAdapter() {
-			public void mouseUp(MouseEvent e) {
-				close();
-			}
-		});
-
-		detailTwistie = new TwistieSection(parent, TwistieLabel.SHOW_SEPARATOR);
-
-		detailTwistie.setVisible(false);
-
-		FormData detailTwistieData = new FormData();
-		detailTwistieData.left = new FormAttachment(0, 20);
-		detailTwistieData.right = new FormAttachment(100, -20);
-		detailTwistieData.top = new FormAttachment(messageLabel, 20);
-		detailTwistieData.bottom = new FormAttachment(closeButton, -20);
-		detailTwistie.setLayoutData(detailTwistieData);
-
-		detailTwistie.setTitle("Detail:");
-
-		Composite sectionContent = detailTwistie.getContent();
-		detailTwistie.setForeground(ColorCache.getColor(parent.getDisplay(), 206,
-				206, 206));
-		//		detailTwistie.setBackground(ColorCache.getColor(parent.getDisplay(),
-		//				13, 13, 13));
-
-		sectionContent.setLayout(new FormLayout());
-		detailListWidget = new StyledText(sectionContent, SWT.V_SCROLL | SWT.WRAP);
-		detailListWidget.setEditable(false);
-
-		FormData detailListWidgetData = new FormData();
-		detailListWidgetData.left = new FormAttachment(0, 0);
-		detailListWidgetData.right = new FormAttachment(100, 0);
-		detailListWidgetData.top = new FormAttachment(0, 0);
-		detailListWidgetData.bottom = new FormAttachment(100, 0);
-		detailListWidgetData.height = 100;
-		detailListWidgetData.width = 300;
-		detailListWidget.setLayoutData(detailListWidgetData);
-
-		detailListWidget.setBackground(ColorCache.getColor(parent.getDisplay(),
-				255, 255, 230));
-
-		detailTwistie.addTwistieListener(new ITwistieListener() {
-
-			public void isCollapsed(boolean value) {
-				if (null != getShell() && false == getShell().isDisposed()) {
-					getShell().pack(true);
-				}
-			}
-		});
-
-	}
-
-	public void open() {
-		messageLabel.setText(message != null ? message : "");
-		messageLabel.setSize(messageLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
-
-		if (null != title) {
-			titleLabel.setText(title);
-		}
-		if (null != detailMessages && false == detailMessages.isEmpty()) {
-			boolean hasError = false;
-			for (Iterator iterator = detailMessages.iterator(); iterator.hasNext();) {
-				Object obj = (Object) iterator.next();
-				if (obj instanceof ProgressReportMessage) {
-					ProgressReportMessage message = (ProgressReportMessage) obj;
-
-					if (false == hasError && true == message.isError()) {
-						hasError = true;
-					}
-					appendToDetail(message.getValue(), message.isError());
-				}
-
-			}
-
-			detailTwistie.setVisible(hasError);
-		} else {
-			detailListWidget.setText("");
-			detailTwistie.setVisible(false);
-		}
-		getShell().pack(true);
-		super.open();
-	}
-
-	/**
-	 * Appends the given message to the detail panel; render the message in error color if specified
-	 * @param value
-	 * @param isError if <code>true</code> then render the message in the system error color; otherwise render in default color
-	 */
-	private void appendToDetail(String value, boolean isError) {
-
-		if (null == value || value.length() < 1) {
-			return;
-		}
-
-		if (null == detailListWidget || detailListWidget.isDisposed()) {
-			return;
-		}
-
-		int charCount = detailListWidget.getCharCount();
-		detailListWidget.append(value + "\n");
-		if (true == isError) {
-			StyleRange style2 = new StyleRange();
-			style2.start = charCount;
-			style2.length = value.length();
-			style2.foreground = errorColor;
-			detailListWidget.setStyleRange(style2);
-		}
-
-	}
-
-	public String getMessage() {
-		return message;
-	}
-
-	public void setMessage(String successMessage) {
-		this.message = successMessage;
-	}
-
-	public List getDetailMessages() {
-		return detailMessages;
-	}
-
-	public void setDetailMessages(List detailMessages) {
-		this.detailMessages = detailMessages;
-	}
-
-	public String getTitle() {
-		return title;
-	}
-
-	public void setTitle(String title) {
-		this.title = title;
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/shells/friends/AddFriendsPage.java b/com/aelitis/azureus/ui/swt/shells/friends/AddFriendsPage.java
deleted file mode 100644
index b2f75f5..0000000
--- a/com/aelitis/azureus/ui/swt/shells/friends/AddFriendsPage.java
+++ /dev/null
@@ -1,512 +0,0 @@
-package com.aelitis.azureus.ui.swt.shells.friends;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.ByteFormatter;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.components.shell.LightBoxShell;
-import org.gudy.azureus2.ui.swt.progress.ProgressReportMessage;
-import org.gudy.azureus2.ui.swt.shells.AbstractWizardPage;
-import org.gudy.azureus2.ui.swt.shells.MultipageWizard;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.VuzeShareable;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.messenger.ClientMessageContext;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentV3;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.browser.BrowserContext;
-import com.aelitis.azureus.ui.swt.browser.listener.AbstractBuddyPageListener;
-import com.aelitis.azureus.ui.swt.browser.listener.AbstractStatusListener;
-import com.aelitis.azureus.ui.swt.browser.listener.DisplayListener;
-import com.aelitis.azureus.ui.swt.shells.MessageWindow;
-import com.aelitis.azureus.ui.swt.shells.StyledMessageWindow;
-import com.aelitis.azureus.ui.swt.utils.SWTLoginUtils;
-import com.aelitis.azureus.ui.swt.views.skin.FriendsToolbar;
-import com.aelitis.azureus.ui.swt.views.skin.SkinViewManager;
-import com.aelitis.azureus.util.ConstantsVuze;
-
-public class AddFriendsPage
-	extends AbstractWizardPage
-{
-	public static final String ID = "add.friends.wizard.page";
-
-	public static final String BUTTON_PREVIEW = "button.preview";
-
-	public static final String BUTTON_CONTINUE = "button.continue";
-	
-	
-
-	private Composite content;
-
-	private Browser browser;
-
-	private BrowserContext context;
-
-	private AbstractBuddyPageListener buddyPageListener;
-
-	private FriendsToolbar friendsToolbar;
-
-	private boolean previewMode = false;
-	
-	private boolean isStandalone;
-	
-	private SharePage sharePage;
-
-	private String message = null;
-	
-	public AddFriendsPage(MultipageWizard wizard) {
-		this(wizard,null);
-	}
-	
-	public AddFriendsPage(MultipageWizard wizard,SharePage sharePage) {
-		super(wizard);
-		this.sharePage = sharePage;
-		this.isStandalone = sharePage == null;
-	}
-
-	public Composite createControls(Composite parent) {
-		if(isStandalone) {
-			getWizard().getShell().addListener(SWT.Dispose, new Listener() {
-				public void handleEvent(Event arg0) {
-					friendsToolbar.reset();
-				}
-			});
-		}
-		
-		content = super.createControls(parent);
-		content.setLayout(new FillLayout());
-
-		friendsToolbar = (FriendsToolbar) SkinViewManager.getByClass(FriendsToolbar.class);
-		Color bg = parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
-		
-		byte[] color = new byte[3];
-		
-		color[0] = (byte) bg.getRed();
-		color[1] = (byte) bg.getGreen();
-		color[2] = (byte) bg.getBlue();
-		
-		browser = new Browser(content, Utils.getInitialBrowserStyle(SWT.NONE));
-		
-		String url = ConstantsVuze.getDefaultContentNetwork().getAddFriendURL( ByteFormatter.nicePrint(color));		
-
-		browser.setUrl(url);
-
-		getMessageContext();
-		
-		return content;
-	}
-
-	public void setMessage(String message) {
-		this.message = message;
-	}
-	
-	public String getPageID() {
-		return ID;
-	}
-
-	public String getDesciption() {
-		return MessageText.getString("v3.AddFriends.header.message");
-	}
-
-	public String getTitle() {
-		return MessageText.getString("v3.AddFriends.header");
-	}
-
-	public String getWindowTitle() {
-		return MessageText.getString("v3.AddFriends.wizard.title");
-	}
-
-	protected void createButtons(Composite buttonPanel) {
-		createButton(BUTTON_CANCEL, isStandalone ? MessageText.getString("Button.cancel") : MessageText.getString("wizard.previous"),
-				new SelectionListener() {
-					public void widgetSelected(SelectionEvent e) {
-						if(previewMode && !isStandalone) {
-							previewMode = false;
-							context.executeInBrowser("previewCancel()");
-							showButton(BUTTON_PREVIEW, true);
-						} else {
-							if(isStandalone) {
-								getWizard().close();
-							} else {
-								getWizard().showPage(SharePage.ID);
-							}
-						}
-						
-					}
-
-					public void widgetDefaultSelected(SelectionEvent e) {
-					}
-				});
-		
-		
-		createButton(BUTTON_PREVIEW, MessageText.getString("Button.preview"),
-				new SelectionListener() {
-					public void widgetSelected(SelectionEvent e) {
-						previewMode = true;
-						context.executeInBrowser("preview()");
-						showButton(BUTTON_PREVIEW, false);
-						if(isStandalone) {
-							showButton(BUTTON_BACK, true);
-							enableButton(BUTTON_BACK, true);
-						}
-					}
-
-					public void widgetDefaultSelected(SelectionEvent e) {
-					}
-				});
-		enableButton(BUTTON_PREVIEW, false);
-		
-		//Back for canceling the preview : only used in standalone mode
-		if(isStandalone) {
-			createButton(BUTTON_BACK, MessageText.getString("Button.back"),
-					new SelectionListener() {
-						public void widgetSelected(SelectionEvent e) {
-							context.executeInBrowser("previewCancel()");
-							showButton(BUTTON_BACK, false);
-							showButton(BUTTON_PREVIEW, true);
-						}
-	
-						public void widgetDefaultSelected(SelectionEvent e) {
-						}
-					});
-			showButton(BUTTON_BACK, false);
-		}
-		
-		
-		createButton(BUTTON_OK, isStandalone ? MessageText.getString("Button.send") : MessageText.getString("Button.continue"),
-				new SelectionListener() {
-					public void widgetSelected(SelectionEvent e) {
-						context.executeInBrowser("inviteSubmit()");
-					}
-
-					public void widgetDefaultSelected(SelectionEvent e) {
-					}
-				});
-		enableButton(BUTTON_OK, !isStandalone);
-		
-	}
-
-	public Browser getBrowser() {
-		return browser;
-	}
-
-	public boolean isInitOnStartup() {
-		return true;
-	}
-
-	public synchronized ClientMessageContext getMessageContext() {
-		if (null == context) {
-			context = new BrowserContext(
-					"buddy-page-listener-invite" + Math.random(), getBrowser(), null,
-					true);
-
-			context.addMessageListener(new DisplayListener(getBrowser()));
-
-			/*
-			 * Add listener to call the 'inviteFromShare' script; this listener is only called
-			 * once whenever a web page is loaded the first time or when it's refreshed
-			 */
-			context.addMessageListener(new AbstractStatusListener("status") {
-				public void handlePageLoadCompleted() {
-					/*
-					 * Setting inviteFromShare to false in the browser
-					 */
-					context.executeInBrowser("inviteFromShare(" + !isStandalone + ")");
-					context.removeMessageListener(this);
-					
-					if(message != null) {
-						getMessageContext().executeInBrowser(
-								"preSelect(\"" + message + "\")");
-					}
-				}
-			});
-			/*
-			 * Add the appropriate messaging listeners
-			 */
-
-			buddyPageListener = new AbstractBuddyPageListener(getBrowser()) {
-
-				public void handleCancel() {
-					if (null != friendsToolbar) {
-						friendsToolbar.reset();
-					}
-					if (true == isStandalone()) {
-						getWizard().close();
-					} else {
-						getWizard().performBack();
-					}
-
-				}
-
-				public void handleClose() {
-
-					if (null != friendsToolbar) {
-						friendsToolbar.reset();
-					}
-					
-					getWizard().close();
-					
-				}
-
-				public void handleBuddyInvites() {
-
-					if(sharePage != null) {
-						Utils.execSWTThread(new AERunnable() {
-							public void runSupport() {
-								sharePage.inviteeList.clear();
-								for (Iterator iterator = getInvitedBuddies().iterator(); iterator.hasNext();) {
-									VuzeBuddy buddy = (VuzeBuddy) iterator.next();
-									sharePage.inviteeList.addFriend(buddy);
-								}
-							}
-						});
-					}
-
-				}
-
-				public void handleEmailInvites() {
-					if(sharePage != null) {
-						Utils.execSWTThread(new AERunnable() {
-							public void runSupport() {
-								for (Iterator iterator = getInvitedEmails().iterator(); iterator.hasNext();) {
-									VuzeBuddy buddy = VuzeBuddyManager.createPotentialBuddy(null);
-									buddy.setLoginID((iterator.next()).toString());
-									sharePage.inviteeList.addFriend(buddy);
-								}
-								getWizard().performBack();
-							}
-						});
-					}
-
-				}
-
-				public void handleInviteConfirm() {
-					final Map confirmationResponse = getConfirmationResponse();
-
-					if (null != confirmationResponse) {
-						SWTLoginUtils.waitForLogin(new SWTLoginUtils.loginWaitListener() {
-							public void loginComplete() {
-								Utils.execSWTThread(new AERunnable() {
-									public void runSupport() {
-										try {
-											VuzeShareable shareItem = null;
-											String commentText = null;
-											VuzeBuddy[] buddies = null;
-											List buddiesToShareWith = null;
-											if(sharePage != null) {
-												shareItem = sharePage.getShareItem();
-												commentText = sharePage.getCommentText();
-												buddiesToShareWith = sharePage.getFriends();
-												buddies = (VuzeBuddy[]) buddiesToShareWith.toArray(new VuzeBuddy[buddiesToShareWith.size()]);
-											}
-																						
-											VuzeBuddyManager.inviteWithShare(confirmationResponse,
-													shareItem, commentText, buddies);
-											
-											handleClose();
-											if(buddiesToShareWith != null) {
-												showConfirmationDialog(buddiesToShareWith);
-											} else {
-												showConfirmationDialog();
-											}
-											//resetControls();
-										} catch (NotLoggedInException e) {
-											//Do nothing if login failed; leaves the Share page open... the user can then click cancel to dismiss or 
-											// try again
-										}
-									}
-								});
-							}
-						});
-						
-					}
-				}
-
-				public void handleResize() {
-//					if (true == "maximize".equals(getWindowState())) {
-//						fullScreen(true);
-//					} else if (true == "restore".equals(getWindowState())) {
-//						fullScreen(false);
-//					}
-				}
-				
-				public void handleNbBuddiesUpdated(int nbInvites) {
-					enableButton(BUTTON_OK,nbInvites > 0 || !isStandalone);
-					enableButton(BUTTON_PREVIEW,nbInvites > 0 );
-				}
-
-			};
-
-			context.addMessageListener(buddyPageListener);
-		}
-		return context;
-	}
-
-	public void refresh() {
-		/*
-		 * Calling to init the browser if it's not been done already
-		 */
-		if (null == browser) {
-			getBrowser();
-		}
-		browser.refresh();
-	}
-
-	private void showConfirmationDialog(List buddiesToShareWith) {
-
-		if (null != buddyPageListener) {
-
-			final String[] message = new String[1];
-			final List messages = new ArrayList();
-
-			if (null == buddiesToShareWith) {
-				buddiesToShareWith = Collections.EMPTY_LIST;
-			}
-
-			/*
-			 * Share only
-			 */
-			if (buddyPageListener.getInvitationsSent() == 0) {
-				/*
-				 * The main message to display
-				 */
-				if (buddiesToShareWith.size() > 1) {
-					message[0] = MessageText.getString("message.confirm.share.plural");
-				} else {
-					message[0] = MessageText.getString("message.confirm.share.singular");
-				}
-			}
-
-			/*
-			 * Share with invitations
-			 */
-			else {
-
-				boolean hasError = false;
-				List inviteMessages = buddyPageListener.getConfirmationMessages();
-				for (Iterator iterator = inviteMessages.iterator(); iterator.hasNext();) {
-					ProgressReportMessage cMessage = (ProgressReportMessage) iterator.next();
-					if (true == cMessage.isError()) {
-						hasError = true;
-						break;
-					}
-				}
-
-				if (true == hasError) {
-					message[0] = MessageText.getString("message.confirm.invite.error");
-					messages.addAll(buddyPageListener.getConfirmationMessages());
-				} else {
-					/*
-					 * The main message to display
-					 */
-					if (buddiesToShareWith.size()
-							+ buddyPageListener.getInvitationsSent() == 1) {
-						message[0] = MessageText.getString("message.confirm.share.invite.singular");
-					} else {
-						message[0] = MessageText.getString("message.confirm.share.invite.plural");
-					}
-				}
-			}
-
-			Utils.execSWTThreadLater(0, new AERunnable() {
-
-				public void runSupport() {
-					Shell mainShell = UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell();
-					MessageWindow messageWindow = new MessageWindow(
-							mainShell, 6);
-
-					messageWindow.setDetailMessages(messages);
-					messageWindow.setMessage(message[0]);
-					messageWindow.setTitle("Share confirmation");
-					messageWindow.setSize(400, 300);
-
-					Utils.centerWindowRelativeTo(messageWindow.getShell(),mainShell);
-					
-					messageWindow.open();
-
-				}
-			});
-		}
-	}
-	
-	private void showConfirmationDialog() {
-		if (null != buddyPageListener) {
-			Utils.execSWTThreadLater(0, new AERunnable() {
-
-				public void runSupport() {
-					Shell mainShell = UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell();
-					MessageWindow messageWindow = new MessageWindow(
-							mainShell, 6);
-
-					messageWindow.setDetailMessages(buddyPageListener.getConfirmationMessages());
-					messageWindow.setMessage(buddyPageListener.getFormattedInviteMessage());
-
-					messageWindow.setTitle("Invite confirmation");
-					messageWindow.setSize(400, 300);
-
-					Utils.centerWindowRelativeTo(messageWindow.getShell(),mainShell);
-					
-					messageWindow.open();
-
-
-				}
-			});
-		}
-	}
-
-	/**
-	 * Opens the invite-friend page.
-	 * Pre-select a friend or Friends by calling the preSelect method in the browser
-	 * and passing on the specially formatted message
-	 * @param message
-	 */
-	public void inviteWithMessage(final String message) {
-
-		if (null != friendsToolbar) {
-			friendsToolbar.setAddFriendsMode();
-		}
-		//		addRefreshListener(new IDetailPage.RefreshListener() {
-		//			public boolean runOnlyOnce() {
-		//				return true;
-		//			}
-		//
-		//			public void refreshCompleted() {
-		//				Utils.execSWTThreadLater(0, new AERunnable() {
-		//					public void runSupport() {
-		//						getMessageContext().executeInBrowser(
-		//								"preSelect(\"" + message + "\")");
-		//					}
-		//				});
-		//
-		//			}
-		//		});
-
-	}
-
-	public void setStandalone(boolean isStandalone) {
-		this.isStandalone = isStandalone;
-	}
-
-	public boolean isStandalone() {
-		return isStandalone;
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/shells/friends/SharePage.java b/com/aelitis/azureus/ui/swt/shells/friends/SharePage.java
deleted file mode 100644
index 7fdf386..0000000
--- a/com/aelitis/azureus/ui/swt/shells/friends/SharePage.java
+++ /dev/null
@@ -1,744 +0,0 @@
-package com.aelitis.azureus.ui.swt.shells.friends;
-
-import java.io.ByteArrayInputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.custom.StyleRange;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.DisplayFormatters;
-import org.gudy.azureus2.core3.util.SystemTime;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.shells.AbstractWizardPage;
-import org.gudy.azureus2.ui.swt.shells.MultipageWizard;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.VuzeShareable;
-import com.aelitis.azureus.core.messenger.ClientMessageContext;
-import com.aelitis.azureus.core.messenger.config.PlatformBuddyMessenger;
-import com.aelitis.azureus.core.messenger.config.PlatformConfigMessenger;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.ui.swt.browser.BrowserContext;
-import com.aelitis.azureus.ui.swt.browser.listener.AbstractBuddyPageListener;
-import com.aelitis.azureus.ui.swt.buddy.VuzeBuddySWT;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.utils.TorrentUIUtilsV3;
-import com.aelitis.azureus.ui.swt.utils.TorrentUIUtilsV3.ContentImageLoadedListener;
-import com.aelitis.azureus.ui.swt.views.skin.BuddiesViewer;
-import com.aelitis.azureus.ui.swt.views.skin.FriendsToolbar;
-import com.aelitis.azureus.ui.swt.views.skin.SkinViewManager;
-import com.aelitis.azureus.ui.swt.views.skin.widgets.FriendsList;
-import com.aelitis.azureus.ui.utils.ImageBytesDownloader;
-import com.aelitis.azureus.ui.utils.ImageBytesDownloader.ImageDownloaderListener;
-import com.aelitis.azureus.util.JSONUtils;
-
-public class SharePage
-	extends AbstractWizardPage
-{
-	public static final String ID = "share.wizard.page";
-
-	private Composite content;
-
-	private FriendsList buddyList;
-
-	private Composite inviteePanel;
-
-	FriendsList inviteeList;
-
-	private Button addBuddyButton;
-
-	private Text messageText;
-
-	private BuddiesViewer buddiesViewer;
-
-	private FriendsToolbar friendsToolbar;
-
-	private BrowserContext context;
-
-	private AbstractBuddyPageListener buddyPageListener;
-
-	private VuzeShareable shareItem;
-
-	private String referer;
-
-	private Label contentThumbnail;
-
-	private Browser browser;
-
-	private Composite contentDetail;
-
-	private StyledText contentStats;
-
-	private Font contentTitleFont = null;
-
-	public SharePage(MultipageWizard wizard) {
-		super(wizard);
-	}
-
-	public Composite createControls(Composite parent) {
-		content = super.createControls(parent);
-
-		buddiesViewer = (BuddiesViewer) SkinViewManager.getByClass(BuddiesViewer.class);
-		friendsToolbar = (FriendsToolbar) SkinViewManager.getByClass(FriendsToolbar.class);
-
-		getWizard().getShell().addListener(SWT.Dispose, new Listener() {
-			public void handleEvent(Event arg0) {
-				resetBuddyViewer();
-			}
-		});
-		
-		content.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
-		content.setBackgroundMode(SWT.INHERIT_FORCE);
-		
-		content.setLayout(new GridLayout(2, false));
-		createContentDetail();
-		createFriendsPanel();
-		createOptionalMessage();
-
-		return content;
-	}
-
-	private void createContentDetail() {
-		contentDetail = new Composite(content, SWT.NONE);
-		contentDetail.setBackgroundMode(SWT.INHERIT_DEFAULT);
-		GridData gData = new GridData(SWT.FILL, SWT.TOP, true, false);
-		gData.horizontalSpan = 2;
-		contentDetail.setLayoutData(gData);
-
-		contentDetail.setLayout(new GridLayout(2, false));
-
-		contentThumbnail = new Label(contentDetail, SWT.NONE);
-		gData = new GridData(SWT.BEGINNING, SWT.FILL, false, false);
-		gData.widthHint = 142;
-		gData.heightHint = 82;
-		contentThumbnail.setLayoutData(gData);
-
-		contentStats = new StyledText(contentDetail, SWT.WRAP);
-		contentStats.setBackground(contentDetail.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
-
-		contentStats.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
-		contentStats.getCaret().setVisible(false);
-		contentStats.setEnabled(false);
-		contentStats.setEditable(false);
-	}
-
-	private void createFriendsPanel() {
-		Composite friendsPanel = new Composite(content, SWT.NONE);
-		friendsPanel.setLayout(new FillLayout(SWT.HORIZONTAL));
-		friendsPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
-		createExistingFriendsList(friendsPanel);
-		createNewFriendsList(friendsPanel);
-	}
-
-	private void createExistingFriendsList(Composite parent) {
-		buddyList = new FriendsList(parent);
-		buddyList.setBuddiesViewer(buddiesViewer);
-		
-
-		buddyList.setDefault_prompt_text(MessageText.getString("message.prompt.add.friends"));
-		Image imageBuddyPrompt = ImageLoader.getInstance().getImage(
-				"buddy_prompt_image");
-		buddyList.setDefault_prompt_image(imageBuddyPrompt);
-		parent.addDisposeListener(new DisposeListener() {
-			public void widgetDisposed(DisposeEvent e) {
-				ImageLoader.getInstance().releaseImage("buddy_prompt_image");
-			}
-		});
-	}
-
-	private void createNewFriendsList(Composite parent) {
-		inviteePanel = new Composite(parent, SWT.NONE);
-		GridLayout gLayout = new GridLayout(2, false);
-		gLayout.marginWidth = 0;
-		gLayout.marginHeight = 0;
-		gLayout.marginBottom = 5;
-		inviteePanel.setLayout(gLayout);
-
-		inviteeList = new FriendsList(inviteePanel);
-
-		inviteeList.setEmailDisplayOnly(true);
-
-		GridData gData = new GridData(SWT.FILL, SWT.FILL, true, true);
-		gData.horizontalSpan = 2;
-		inviteeList.getControl().setLayoutData(gData);
-
-		Label addBuddyPromptLabel = new Label(inviteePanel, SWT.NONE | SWT.WRAP
-				| SWT.RIGHT);
-		addBuddyPromptLabel.setLayoutData(new GridData(SWT.END, SWT.CENTER, true,
-				false));
-		addBuddyPromptLabel.setText(MessageText.getString("v3.Share.invite.buddies.prompt"));
-
-		addBuddyButton = new Button(inviteePanel, SWT.PUSH);
-		gData = new GridData(SWT.END, SWT.CENTER, true, false);
-		gData.widthHint = 130;
-		addBuddyButton.setLayoutData(gData);
-		addBuddyButton.setText(MessageText.getString("v3.Share.add.buddy"));
-		addBuddyButton.addSelectionListener(new SelectionListener() {
-			public void widgetSelected(SelectionEvent e) {
-				getWizard().showPage(AddFriendsPage.ID);
-				friendsToolbar.enableShareButton(false);
-			}
-
-			public void widgetDefaultSelected(SelectionEvent e) {
-			}
-		});
-
-	}
-
-	private void createOptionalMessage() {
-		Composite messagePanel = new Composite(content, SWT.NONE);
-		GridData gData = new GridData(SWT.FILL, SWT.BOTTOM, true, false);
-		gData.horizontalSpan = 2;
-		messagePanel.setLayoutData(gData);
-
-		messagePanel.setLayout(new GridLayout());
-
-		Label messageLabel = new Label(messagePanel, SWT.WRAP);
-		messageLabel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-		messageLabel.setText(MessageText.getString("v3.Share.optional.message"));
-
-		messageText = new Text(messagePanel, SWT.WRAP | SWT.BORDER);
-		gData = new GridData(SWT.FILL, SWT.FILL, true, true);
-		gData.heightHint = messageText.computeSize(SWT.DEFAULT, SWT.DEFAULT).y * 2;
-		messageText.setLayoutData(gData);
-		messageText.setTextLimit(140);
-
-		Label messageDisclaimerLabel = new Label(messagePanel, SWT.WRAP);
-		messageDisclaimerLabel.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM,
-				true, false));
-		messageDisclaimerLabel.setText(MessageText.getString("v3.Share.disclaimer"));
-	}
-
-	/**
-	 * Overriding default button
-	 */
-	protected void createButtons(Composite buttonPanel) {
-
-		createButton(BUTTON_CANCEL, MessageText.getString("Button.cancel"),
-				defaultButtonListener);
-
-		createButton(BUTTON_OK, MessageText.getString("v3.Share.send.now"),
-				new SelectionListener() {
-
-					public void widgetSelected(SelectionEvent e) {
-						((Button)e.widget).setEnabled(false);
-						getMessageContext().executeInBrowser(
-								"sendSharingBuddies('" + getCommitJSONMessage() + "')");
-
-						getMessageContext().executeInBrowser(
-								"setShareReferer('" + referer + "')");
-
-						getMessageContext().executeInBrowser("shareSubmit()");
-					}
-
-					public void widgetDefaultSelected(SelectionEvent e) {
-					}
-				});
-	}
-
-	private String getCommitJSONMessage() {
-		if (null == shareItem || null == shareItem.getHash()) {
-			return null;
-		}
-		List buddieloginIDsAndContentHash = new ArrayList();
-		List loginIDs = new ArrayList();
-		for (Iterator iterator = buddyList.getFriends().iterator(); iterator.hasNext();) {
-			VuzeBuddySWT vuzeBuddy = (VuzeBuddySWT) iterator.next();
-			loginIDs.add(vuzeBuddy.getLoginID());
-		}
-		buddieloginIDsAndContentHash.add(loginIDs);
-		buddieloginIDsAndContentHash.add(shareItem.getHash());
-
-		return JSONUtils.encodeToJSON(buddieloginIDsAndContentHash);
-	}
-
-	public void setShareItem(VuzeShareable content, String referer) {
-		this.shareItem = content;
-		this.referer = referer;
-
-		if (SystemTime.getCurrentTime() - PlatformBuddyMessenger.getLastSyncCheck() > PlatformConfigMessenger.getBuddySyncOnShareMinTimeSecs() * 1000) {
-			try {
-				PlatformBuddyMessenger.sync(null);
-			} catch (NotLoggedInException e) {
-			}
-		}
-
-		if (content != null && content.getThumbURL() != null) {
-			ImageBytesDownloader.loadImage(content.getThumbURL(),
-					new ImageDownloaderListener() {
-						public void imageDownloaded(final byte[] image) {
-							Utils.execSWTThread(new AERunnable() {
-								public void runSupport() {
-									if (contentThumbnail != null
-											&& !contentThumbnail.isDisposed()) {
-										ByteArrayInputStream bis = new ByteArrayInputStream(image);
-										final Image img = new Image(Display.getDefault(), bis);
-										if (img != null) {
-											contentThumbnail.addDisposeListener(new DisposeListener() {
-												public void widgetDisposed(DisposeEvent e) {
-													if (img != null && !img.isDisposed()) {
-														img.dispose();
-													}
-												}
-											});
-											contentThumbnail.setImage(img);
-										}
-									}
-								}
-							});
-						}
-					});
-		}
-
-		if (null != shareItem) {
-			if (null != friendsToolbar) {
-				friendsToolbar.setShareMode();
-			}
-
-			//			getDetailPanel().show(true, PAGE_ID);
-			//
-			//// KN: Work in progress for new Share wizard			
-//						ShareWizard shell = new ShareWizard(
-//								UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell(),
-//								SWT.DIALOG_TRIM | SWT.RESIZE);
-//						shell.setText("Vuze - Wizard");
-//						shell.setSize(500, 550);
-//						
-//						/*
-//						 * Opens a centered free-floating shell
-//						 */
-//			
-//						UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-//						if (null == uiFunctions) {
-//							/*
-//							 * Centers on the active monitor
-//							 */
-//							Utils.centreWindow(shell.getShell());
-//						} else {
-//							/*
-//							 * Centers on the main application window
-//							 */
-//							Utils.centerWindowRelativeTo(shell.getShell(),
-//									uiFunctions.getMainShell());
-//						}
-//			
-//						shell.open();
-		}
-	}
-
-	public VuzeShareable getShareItem() {
-		return shareItem;
-	}
-
-	public void performFinish() {
-		System.out.println("TODO: send the share message now!!!!!");
-	}
-
-	public void performCancel() {
-		super.performCancel();
-		resetBuddyViewer();
-	}
-	
-	private void resetBuddyViewer() {
-		buddiesViewer.setShareMode(false,null);
-		friendsToolbar.reset();
-	}
-
-	public void addBuddy(VuzeBuddySWT vuzeBuddy) {
-		if (null == buddyList.findWidget(vuzeBuddy)) {
-			buddyList.addFriend((VuzeBuddy) vuzeBuddy);
-			adjustLayout();
-		}
-	}
-
-	public void removeBuddy(VuzeBuddySWT vuzeBuddy) {
-		if (null != buddyList.findWidget(vuzeBuddy)) {
-			buddyList.removeFriend((VuzeBuddy) vuzeBuddy);
-			adjustLayout();
-		}
-	}
-	private void adjustLayout() {
-/*
-		if (buddyList.getContentCount() > 0 || inviteeList.getContentCount() > 0) {
-			sendNowButton.setEnabled(true);
-		} else {
-			sendNowButton.setEnabled(false);
-		}
-		if (inviteeList.getContentCount() > 0) {
-			showInviteeList(true);
-			addBuddyButton.setText(MessageText.getString("v3.Share.add.edit.buddy"));
-		} else {
-			showInviteeList(false);
-			addBuddyButton.setText(MessageText.getString("v3.Share.add.buddy"));
-		}*/
-
-		content.layout(true, true);
-	}
-	
-	public String getPageID() {
-		return ID;
-	}
-
-	public String getDesciption() {
-		return MessageText.getString("v3.Share.header.message");
-	}
-	
-	public List getFriends() {
-		return buddyList.getFriends();
-	}
-
-	public String getTitle() {
-		return MessageText.getString("v3.Share.header");
-	}
-
-	public String getWindowTitle() {
-		return MessageText.getString("v3.Share.wizard.title");
-	}
-
-	private boolean alreadyShown = false;
-	public void performAboutToBeShown() {
-		
-		super.performAboutToBeShown();
-		friendsToolbar.enableShareButton(true);
-		
-		if(alreadyShown) return;
-		alreadyShown = true;
-
-		
-		/*
-		 * Init the browser if it was not done already
-		 */
-		if (null == browser) {
-			getBrowser();
-		}
-		//browser.refresh();
-
-		if (null != friendsToolbar) {
-			friendsToolbar.setShareMode();
-		}
-
-		if (null != buddiesViewer) {
-			setBuddies(buddiesViewer.getSelection());
-			buddiesViewer.addSelectionToShare();
-			buddiesViewer.setShareMode(true, this);
-		}
-
-
-		TorrentUIUtilsV3.getContentImage(shareItem, true,
-				new ContentImageLoadedListener() {
-			public void contentImageLoaded(Image image, boolean wasReturned) {
-				contentThumbnail.setImage(image);
-			}
-		});
-		
-		contentDetail.addDisposeListener(new DisposeListener() {
-			public void widgetDisposed(DisposeEvent e) {
-				TorrentUIUtilsV3.releaseContentImage(shareItem);
-			}
-		});
-
-		updateContentStats();
-
-	}
-
-	public void setBuddies(List buddies) {
-		buddyList.clear();
-		for (Iterator iterator = buddies.iterator(); iterator.hasNext();) {
-			Object vuzeBuddy = iterator.next();
-			if (vuzeBuddy instanceof VuzeBuddy) {
-				buddyList.addFriend((VuzeBuddy) vuzeBuddy);
-			}
-		}
-	}
-
-	private void updateContentStats() {
-		contentStats.setText("");
-
-		if (shareItem == null) {
-			return;
-		}
-
-		if (null == contentTitleFont) {
-			FontData[] fDatas = contentStats.getFont().getFontData();
-			for (int i = 0; i < fDatas.length; i++) {
-				fDatas[i].height += 2;
-			}
-			contentTitleFont = new Font(contentStats.getDisplay(), fDatas);
-			contentStats.addDisposeListener(new DisposeListener() {
-
-				public void widgetDisposed(DisposeEvent e) {
-					if (null != contentTitleFont
-							&& false == contentTitleFont.isDisposed()) {
-						contentTitleFont.dispose();
-					}
-				}
-			});
-
-		}
-
-		int charCount = contentStats.getCharCount();
-		contentStats.append(shareItem.getDisplayName() + "\n");
-		StyleRange style2 = new StyleRange();
-		style2.start = charCount;
-		style2.length = shareItem.getDisplayName().length();
-		style2.font = contentTitleFont;
-		contentStats.setStyleRange(style2);
-
-		String publisher = shareItem.getPublisher();
-
-		if (null != publisher && publisher.length() > 0) {
-			if (publisher.startsWith("az")) {
-				publisher = publisher.substring(2);
-			}
-			contentStats.append("From: " + publisher + "\n");
-		}
-
-		long size = shareItem.getSize();
-		
-		if ( size > 0 ){
-			
-			contentStats.append("File size: " + DisplayFormatters.formatByteCountToKiBEtc( size ));
-		}
-	}
-	
-	public ClientMessageContext getMessageContext() {
-		AddFriendsPage page = (AddFriendsPage) getWizard().getPage(
-				AddFriendsPage.ID);
-		if (null != page) {
-			browser = page.getBrowser();
-			return page.getMessageContext();
-		}
-		
-		return null;
-	}
-
-//	public ClientMessageContext getMessageContext() {
-//		if (null == context) {
-//			context = new BrowserContext("buddy-page-listener-share" + Math.random(),
-//					getBrowser(), null, true);
-//
-//			context.addMessageListener(new DisplayListener(getBrowser()));
-//
-//			/*
-//			 * Add listener to call the 'inviteFromShare' script; this listener is only called
-//			 * once whenever a web page is loaded the first time or when it's refreshed
-//			 */
-//			context.addMessageListener(new AbstractStatusListener("status") {
-//				public void handlePageLoadCompleted() {
-//					/*
-//					 * Setting inviteFromShare to true in the browser
-//					 */
-//					context.executeInBrowser("inviteFromShare(" + true + ")");
-//
-//					//					SharePage.this.notifyRefreshListeners();
-//
-//				}
-//			});
-//
-//			/*
-//			 * Add the appropriate messaging listeners
-//			 */
-//
-//			buddyPageListener = new AbstractBuddyPageListener(getBrowser()) {
-//
-//				private Map confirmationResponse;
-//
-//				public void handleCancel() {
-////					Utils.execSWTThread(new AERunnable() {
-////						public void runSupport() {
-////							getWizard().showPage(ID);
-////						}
-////					});
-//				}
-//
-//				public void handleClose() {
-////					Utils.execSWTThread(new AERunnable() {
-////						public void runSupport() {
-////							getWizard().showPage(ID);
-////						}
-////					});
-//
-//				}
-//
-//				public void handleBuddyInvites() {
-//
-//					Utils.execSWTThread(new AERunnable() {
-//						public void runSupport() {
-//							inviteeList.clear();
-//							for (Iterator iterator = getInvitedBuddies().iterator(); iterator.hasNext();) {
-//								VuzeBuddy buddy = (VuzeBuddy) iterator.next();
-//								inviteeList.addFriend(buddy);
-//							}
-//						}
-//					});
-//
-//				}
-//
-//				public void handleEmailInvites() {
-//					Utils.execSWTThread(new AERunnable() {
-//						public void runSupport() {
-//							for (Iterator iterator = getInvitedEmails().iterator(); iterator.hasNext();) {
-//								VuzeBuddy buddy = VuzeBuddyManager.createPotentialBuddy(null);
-//								buddy.setLoginID((iterator.next()).toString());
-//								inviteeList.addFriend(buddy);
-//							}
-//						}
-//					});
-//
-//				}
-//
-//				public void handleInviteConfirm() {
-//					confirmationResponse = getConfirmationResponse();
-//
-//					if (null != confirmationResponse) {
-//						final List buddiesToShareWith = buddyList.getFriends();
-//						final VuzeBuddy[] buddies = (VuzeBuddy[]) buddiesToShareWith.toArray(new VuzeBuddy[buddiesToShareWith.size()]);
-//						SWTLoginUtils.waitForLogin(new SWTLoginUtils.loginWaitListener() {
-//							public void loginComplete() {
-//								try {
-//									VuzeBuddyManager.inviteWithShare(confirmationResponse,
-//											getShareItem(), messageText.getText(), buddies);
-//									getWizard().close();
-//									showConfirmationDialog(buddiesToShareWith);
-//
-//								} catch (NotLoggedInException e) {
-//									//Do nothing if login failed; leaves the Share page open... the user can then click cancel to dismiss or 
-//									// try again
-//								}
-//							}
-//						});
-//					}
-//				}
-//
-//				public void handleResize() {
-//				}
-//				
-//				@Override
-//				public void handleNbBuddiesUpdated(int nbInvites) {
-//					// TODO Auto-generated method stub
-//					
-//				}
-//
-//			};
-//			context.addMessageListener(buddyPageListener);
-//		}
-//		return context;
-//	}
-
-	/*
-	private void showConfirmationDialog(List buddiesToShareWith) {
-
-		if (null != buddyPageListener) {
-
-			final String[] message = new String[1];
-			final List messages = new ArrayList();
-
-			if (null == buddiesToShareWith) {
-				buddiesToShareWith = Collections.EMPTY_LIST;
-			}
-
-			//
-			// Share only
-			//
-			if (buddyPageListener.getInvitationsSent() == 0) {
-				//
-				// The main message to display
-				//
-				if (buddiesToShareWith.size() > 1) {
-					message[0] = MessageText.getString("message.confirm.share.plural");
-				} else {
-					message[0] = MessageText.getString("message.confirm.share.singular");
-				}
-			}
-
-			//
-			// Share with invitations
-			//
-			else {
-
-				boolean hasError = false;
-				List inviteMessages = buddyPageListener.getConfirmationMessages();
-				for (Iterator iterator = inviteMessages.iterator(); iterator.hasNext();) {
-					ProgressReportMessage cMessage = (ProgressReportMessage) iterator.next();
-					if (true == cMessage.isError()) {
-						hasError = true;
-						break;
-					}
-				}
-
-				if (true == hasError) {
-					message[0] = MessageText.getString("message.confirm.invite.error");
-					messages.addAll(buddyPageListener.getConfirmationMessages());
-				} else {
-					//
-					// The main message to display
-					//
-					if (buddiesToShareWith.size()
-							+ buddyPageListener.getInvitationsSent() == 1) {
-						message[0] = MessageText.getString("message.confirm.share.invite.singular");
-					} else {
-						message[0] = MessageText.getString("message.confirm.share.invite.plural");
-					}
-				}
-			}
-
-			Utils.execSWTThreadLater(0, new AERunnable() {
-
-				public void runSupport() {
-					final LightBoxShell lightBoxShell = new LightBoxShell(false);
-					StyledMessageWindow messageWindow = new StyledMessageWindow(
-							lightBoxShell.getShell(), 6, true);
-
-					messageWindow.setDetailMessages(messages);
-					messageWindow.setMessage(message[0]);
-					messageWindow.setTitle("Share confirmation");
-					messageWindow.setSize(400, 300);
-
-					messageWindow.addListener(SWT.Dispose, new Listener() {
-						public void handleEvent(Event event) {
-							lightBoxShell.close();
-						}
-					});
-					lightBoxShell.open(messageWindow);
-
-				}
-			});
-		}
-	}
-*/
-
-	private Browser getBrowser() {
-		if (null == browser) {
-
-			AddFriendsPage page = (AddFriendsPage) getWizard().getPage(
-					AddFriendsPage.ID);
-			if (null != page) {
-				browser = page.getBrowser();
-				page.getMessageContext();
-			}
-			
-		}
-
-		return browser;
-	}
-	
-	public String getCommentText() {
-		return messageText.getText();
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/shells/friends/ShareWizard.java b/com/aelitis/azureus/ui/swt/shells/friends/ShareWizard.java
deleted file mode 100644
index 39456c0..0000000
--- a/com/aelitis/azureus/ui/swt/shells/friends/ShareWizard.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.aelitis.azureus.ui.swt.shells.friends;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.gudy.azureus2.ui.swt.shells.MultipageWizard;
-
-public class ShareWizard
-	extends MultipageWizard
-{
-
-	public ShareWizard(Display display, int shellStyle) {
-		super(display, shellStyle);
-	}
-
-	public ShareWizard(Shell parent, int shellStyle) {
-		super(parent, shellStyle);
-	}
-
-	public void createPages() {
-		SharePage sharePage = new SharePage(this);
-		addPage(sharePage);
-		addPage(new AddFriendsPage(this,sharePage));
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/shells/main/DebugMenuHelper.java b/com/aelitis/azureus/ui/swt/shells/main/DebugMenuHelper.java
index 028ea4d..748d1a1 100644
--- a/com/aelitis/azureus/ui/swt/shells/main/DebugMenuHelper.java
+++ b/com/aelitis/azureus/ui/swt/shells/main/DebugMenuHelper.java
@@ -8,12 +8,14 @@ import org.eclipse.swt.widgets.*;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.donations.DonationWindow;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreRunningListener;
-import com.aelitis.azureus.core.drm.msdrm.LicenseAquirer;
+import com.aelitis.azureus.ui.UIFunctionsManager;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
+import com.aelitis.azureus.util.ConstantsVuze;
 
 /**
  * A convenience class for creating the Debug menu
@@ -42,28 +44,6 @@ public class DebugMenuHelper
 		}
 		
 		item = new MenuItem(menuDebug, SWT.CASCADE);
-		item.setText("DRM");
-		item.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event event) {
-				final Shell shell = new Shell(Utils.findAnyShell());
-				//shell.setLayout(new FillLayout());
-				shell.open();
-				final LicenseAquirer la = new LicenseAquirer(shell);
-				Thread t = new Thread() {
-					public void run() {
-						try {
-							la.aquireLicenseFor("SNWEAY7K6RJPAJF2HD52BEX27ERKJXAO");
-						} catch (Exception e) {
-							e.printStackTrace();
-						}
-					}
-				};
-				t.setDaemon(true);
-				t.start();
-			}
-		});
-		
-		item = new MenuItem(menuDebug, SWT.CASCADE);
 		item.setText("Run GC");
 		item.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
@@ -77,7 +57,7 @@ public class DebugMenuHelper
 			public void handleEvent(Event event) {
 				CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
 					public void azureusCoreRunning(AzureusCore core) {
-						Utils.openMessageBox(Utils.findAnyShell(), 0, "Done", "Core Now Avail");
+						new MessageBoxShell(0, "Done", "Core Now Avail").open(null);
 					}
 				});
 			}
@@ -204,6 +184,14 @@ public class DebugMenuHelper
 			}
 		});
 
+		item = new MenuItem(menuDebug, SWT.NONE);
+		item.setText("FB");
+		item.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				UIFunctionsManager.getUIFunctions().viewURL(ConstantsVuze.getDefaultContentNetwork().getSiteRelativeURL("facebookshare.start", true), null, null);
+			}
+		});
+		
 		return item;
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/shells/main/MainMenu.java b/com/aelitis/azureus/ui/swt/shells/main/MainMenu.java
index feb3d1e..be4a326 100644
--- a/com/aelitis/azureus/ui/swt/shells/main/MainMenu.java
+++ b/com/aelitis/azureus/ui/swt/shells/main/MainMenu.java
@@ -1,18 +1,9 @@
 package com.aelitis.azureus.ui.swt.shells.main;
 
-import java.util.Arrays;
-import java.util.Comparator;
-
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.MenuEvent;
-import org.eclipse.swt.events.MenuListener;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.MenuItem;
-import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.widgets.*;
+
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.config.impl.ConfigurationDefaults;
@@ -24,25 +15,16 @@ import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.IMainMenu;
 import org.gudy.azureus2.ui.swt.mainwindow.IMenuConstants;
 import org.gudy.azureus2.ui.swt.mainwindow.MenuFactory;
-import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
 
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.cnetwork.ContentNetworkManager;
-import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
 import com.aelitis.azureus.ui.skin.SkinConstants;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.skin.SWTSkin;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectBrowser;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinUtils;
 import com.aelitis.azureus.ui.swt.toolbar.ToolBarItem;
-import com.aelitis.azureus.ui.swt.utils.ContentNetworkUIManagerWindow;
-import com.aelitis.azureus.ui.swt.views.skin.FriendsToolbar;
 import com.aelitis.azureus.ui.swt.views.skin.SkinViewManager;
 import com.aelitis.azureus.ui.swt.views.skin.ToolBarView;
 import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar.UISWTViewEventListenerSkinObject;
 import com.aelitis.azureus.util.ConstantsVuze;
 import com.aelitis.azureus.util.ContentNetworkUtils;
 
@@ -88,12 +70,8 @@ public class MainMenu
 		//addViewMenu();
 		addSimpleViewMenu();
 
-		addContentNetworksMenu();
-
 		addCommunityMenu();
 
-		addPublishMenu();
-
 		addToolsMenu();
 
 		/*
@@ -119,157 +97,8 @@ public class MainMenu
 		 */
 		MenuFactory.updateEnabledStates(menuBar);
 	}
-
-	/**
-	 * 
-	 *
-	 * @since 4.0.0.3
-	 */
-	private void addContentNetworksMenu() {
-		try {
-			MenuItem contentNetworkItem = MenuFactory.createTopLevelMenuItem(menuBar,
-					MENU_ID_CONTENT_NETWORKS);
-			final Menu contentNetworkMenu = contentNetworkItem.getMenu();
-
-			contentNetworkMenu.addListener(SWT.Show, new Listener() {
-				public void handleEvent(Event event) {
-					try {
-						MenuItem[] menuItems = contentNetworkMenu.getItems();
-						Utils.disposeSWTObjects(menuItems);
-
-						buildContentNetworkMenu(contentNetworkMenu);
-
-					} catch (Exception e) {
-						Debug.out("Error creating Menu", e);
-					}
-
-				}
-			});
-		} catch (Exception e) {
-			Debug.out("Error creating Menu", e);
-		}
-	}
-
-	/**
-	 * @param contentNetworkMenu
-	 *
-	 * @since 4.0.0.3
-	 */
-	protected void buildContentNetworkMenu(final Menu contentNetworkMenu) {
-		ContentNetworkManager cnManager = ContentNetworkManagerFactory.getSingleton();
-		if (cnManager == null) {
-			return;
-		}
-		ContentNetwork[] contentNetworks = cnManager.getContentNetworks();
-		Arrays.sort(contentNetworks, new Comparator() {
-			public int compare(Object o1, Object o2) {
-				String p1 = ""
-						+ ((ContentNetwork) o1).getProperty(ContentNetwork.PROPERTY_ORDER);
-				String p2 = ""
-						+ ((ContentNetwork) o2).getProperty(ContentNetwork.PROPERTY_ORDER);
-
-				return p1.compareTo(p2);
-			}
-		});
-		for (int i = 0; i < contentNetworks.length; i++) {
-			ContentNetwork contentNetwork = contentNetworks[i];
-			addContentNetworkItem(contentNetworkMenu, contentNetwork);
-		}
-		
-		MenuFactory.addSeparatorMenuItem(contentNetworkMenu);
-
-		MenuFactory.addMenuItem(contentNetworkMenu, MENU_ID_CONTENT_NETWORKS
-				+ ".manage", new Listener() {
-			public void handleEvent(Event event) {
-				new ContentNetworkUIManagerWindow();
-			}			
-		});
-
-		MenuFactory.addSeparatorMenuItem(contentNetworkMenu);
-
-		MenuFactory.addMenuItem(contentNetworkMenu, MENU_ID_CONTENT_NETWORKS
-				+ ".about", new Listener() {
-			public void handleEvent(Event event) {
-				String url = "AboutHDNetworks.start";
-				UIFunctionsManagerSWT.getUIFunctionsSWT().viewURL(url, "_blank", 0,
-						0, true, false);
-			}			
-		});
-	}
-
 	
 	/**
-	 * @param contentNetworkMenu
-	 * @param cn
-	 *
-	 * @since 4.0.0.3
-	 */
-	private void addContentNetworkItem(Menu contentNetworkMenu,
-			ContentNetwork cn) {
-		if (cn == null) {
-			return;
-		}
-
-		Object prop = cn.getProperty(ContentNetwork.PROPERTY_REMOVEABLE);
-		boolean removable = (prop instanceof Boolean) ? ((Boolean) prop).booleanValue()
-				: false;
-		
-		if (removable) {
-  		prop = cn.getPersistentProperty(ContentNetwork.PP_SHOW_IN_MENU);
-  		boolean show = (prop instanceof Boolean) ? ((Boolean) prop).booleanValue()
-  				: true;
-  		
-  		if (!show) {
-  			return;
-  		}
-		}
-
-
-		final MenuItem item = MenuFactory.addMenuItem(contentNetworkMenu,
-				SWT.CHECK,
-				null,
-				new Listener() {
-					public void handleEvent(Event event) {
-						MenuItem item = (MenuItem) event.widget;
-						ContentNetwork contentNetwork = (ContentNetwork) item.getData("ContentNetwork");
-						if (contentNetwork == null) {
-							return;
-						}
-
-						SideBar sideBar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-						if (sideBar == null) {
-							return;
-						}
-						String sidebarID = ContentNetworkUtils.getTarget(contentNetwork);
-
-						ContentNetworkUtils.setSourceRef(contentNetwork, "menu", false);
-						sideBar.showEntryByTabID(sidebarID);
-					}
-				});
-
-		item.setText(cn.getName());
-
-		item.setData("ContentNetwork", cn);
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 3.1.1.1
-	 */
-	private void addPublishMenu() {
-		try {
-			MenuItem publishItem = MenuFactory.createPublishMenuItem(menuBar);
-			final Menu publishMenu = publishItem.getMenu();
-
-			addPublishMenuItems(publishMenu);
-
-		} catch (Exception e) {
-			Debug.out("Error creating View Menu", e);
-		}
-	}
-
-	/**
 	 * Creates the File menu and all its children
 	 */
 	private void addFileMenu() {
@@ -278,20 +107,13 @@ public class MainMenu
 		builFileMenu(fileMenu);
 
 		fileMenu.addListener(SWT.Show, new Listener() {
-			private boolean isAZ3_ADV = MenuFactory.isAZ3_ADV;
-
 			public void handleEvent(Event event) {
-				if (isAZ3_ADV != MenuFactory.isAZ3_ADV) {
-
-					MenuItem[] menuItems = fileMenu.getItems();
-					for (int i = 0; i < menuItems.length; i++) {
-						menuItems[i].dispose();
-					}
-
-					builFileMenu(fileMenu);
-
-					isAZ3_ADV = MenuFactory.isAZ3_ADV;
+				MenuItem[] menuItems = fileMenu.getItems();
+				for (int i = 0; i < menuItems.length; i++) {
+					menuItems[i].dispose();
 				}
+
+				builFileMenu(fileMenu);
 			}
 		});
 	}
@@ -310,7 +132,7 @@ public class MainMenu
 
 		int userMode = COConfigurationManager.getIntParameter("User Mode");
 
-		if ( MenuFactory.isAZ3_ADV || userMode > 0 ){
+		if ( userMode > 0 ){
 			Menu shareSubMenu = MenuFactory.createShareMenuItem(fileMenu).getMenu();
 			MenuFactory.addShareFileMenuItem(shareSubMenu);
 			MenuFactory.addShareFolderMenuItem(shareSubMenu);
@@ -331,9 +153,11 @@ public class MainMenu
 		/*
 		 * No need for restart and exit on OS X since it's already handled on the application menu
 		 */
-		if (false == Constants.isOSX) {
+		if (!Utils.isCarbon) {
 			MenuFactory.addSeparatorMenuItem(fileMenu);
 			MenuFactory.addRestartMenuItem(fileMenu);
+		}
+		if (!Constants.isOSX) {
 			MenuFactory.addExitMenuItem(fileMenu);
 		}
 	}
@@ -587,13 +411,6 @@ public class MainMenu
 								SkinConstants.VIEWID_PLUGINBAR, true, 0);
 					}
 
-					if (null == MenuFactory.findMenuItem(viewToolBarsMenu, PREFIX_V3
-							+ ".view." + SkinConstants.VIEWID_BUDDIES_VIEWER)) {
-						createViewMenuItem(skin, viewToolBarsMenu, PREFIX_V3 + ".view."
-								+ SkinConstants.VIEWID_BUDDIES_VIEWER, "Friends.visible",
-								SkinConstants.VIEWID_BUDDIES_VIEWER, true, -1);
-					}
-
 				}
 
 				public void menuHidden(MenuEvent e) {
@@ -622,82 +439,6 @@ public class MainMenu
 			}
 		});
 
-		MenuFactory.addMenuItem(viewMenu, PREFIX_V3 + ".publish", new Listener() {
-			public void handleEvent(Event event) {
-				SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-				sidebar.showEntryByID(SideBar.SIDEBAR_SECTION_PUBLISH);
-			}
-		});
-
-	}
-
-	private void addPublishMenuItems(Menu publishMenu) {
-		MenuFactory.addMenuItem(publishMenu, PREFIX_V3 + ".publish.new",
-				new Listener() {
-					public void handleEvent(Event event) {
-						String sURL = ContentNetworkUtils.getUrl(
-								ConstantsVuze.getDefaultContentNetwork(),
-								ContentNetwork.SERVICE_PUBLISH_NEW);
-
-						SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-						SideBarEntrySWT entry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_PUBLISH);
-						if (entry.getIView() == null) {
-							entry = sidebar.createEntryFromSkinRef(
-									SideBar.SIDEBAR_SECTION_BROWSE,
-									SideBar.SIDEBAR_SECTION_PUBLISH, "publishtab.area",
-									"Publish", null, sURL, true, -1);
-						} else {
-							UISWTViewEventListener eventListener = entry.getEventListener();
-							if (eventListener instanceof UISWTViewEventListenerSkinObject) {
-								SWTSkinObject so = ((UISWTViewEventListenerSkinObject) eventListener).getSkinObject();
-								if (so instanceof SWTSkinObjectBrowser) {
-									((SWTSkinObjectBrowser) so).setURL(sURL);
-								}
-							}
-						}
-						sidebar.showEntryByID(SideBar.SIDEBAR_SECTION_PUBLISH);
-					}
-				});
-
-		MenuFactory.addMenuItem(publishMenu, PREFIX_V3 + ".publish.mine",
-				new Listener() {
-					public void handleEvent(Event event) {
-						String sURL = ContentNetworkUtils.getUrl(
-								ConstantsVuze.getDefaultContentNetwork(),
-								ContentNetwork.SERVICE_PUBLISH);
-
-						SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-						SideBarEntrySWT entry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_PUBLISH);
-						if (entry.getIView() == null) {
-							entry = sidebar.createEntryFromSkinRef(
-									SideBar.SIDEBAR_SECTION_BROWSE,
-									SideBar.SIDEBAR_SECTION_PUBLISH, "publishtab.area",
-									"Publish", null, sURL, true, -1);
-						} else {
-							UISWTViewEventListener eventListener = entry.getEventListener();
-							if (eventListener instanceof UISWTViewEventListenerSkinObject) {
-								SWTSkinObject so = ((UISWTViewEventListenerSkinObject) eventListener).getSkinObject();
-								if (so instanceof SWTSkinObjectBrowser) {
-									((SWTSkinObjectBrowser) so).setURL(sURL);
-								}
-							}
-						}
-						sidebar.showEntryByID(SideBar.SIDEBAR_SECTION_PUBLISH);
-					}
-				});
-
-		MenuFactory.addSeparatorMenuItem(publishMenu);
-
-		MenuFactory.addMenuItem(publishMenu, PREFIX_V3 + ".publish.about",
-				new Listener() {
-					public void handleEvent(Event event) {
-						String sURL = ContentNetworkUtils.getUrl(
-								ConstantsVuze.getDefaultContentNetwork(),
-								ContentNetwork.SERVICE_PUBLISH_ABOUT);
-						Utils.launch(sURL);
-					}
-				});
-
 	}
 
 	/**
@@ -714,6 +455,7 @@ public class MainMenu
 
 		MenuFactory.addTransferBarToMenu(toolsMenu);
 		MenuFactory.addAllPeersMenuItem(toolsMenu);
+		MenuFactory.addClientStatsMenuItem(toolsMenu);
 		MenuFactory.addBlockedIPsMenuItem(toolsMenu);
 
 		MenuFactory.addSeparatorMenuItem(toolsMenu);
@@ -790,8 +532,7 @@ public class MainMenu
 	 * Creates the Torrent menu and all its children
 	 */
 	private void addTorrentMenu() {
-		MenuFactory.setEnablementKeys(MenuFactory.createTorrentMenuItem(menuBar),
-				FOR_AZ2 | FOR_AZ3_ADV);
+		MenuFactory.createTorrentMenuItem(menuBar);
 	}
 
 	public Menu getMenu(String id) {
@@ -839,18 +580,6 @@ public class MainMenu
 						ConstantsVuze.getDefaultContentNetwork(), ContentNetwork.SERVICE_FAQ));
 			}
 		});
-
-		MenuFactory.addSeparatorMenuItem(communityMenu);
-
-		MenuFactory.addMenuItem(communityMenu, MENU_ID_COMMUNITY_ADD_FRIENDS,
-				new Listener() {
-					public void handleEvent(Event e) {
-						FriendsToolbar friendsToolbar = (FriendsToolbar) SkinViewManager.getByClass(FriendsToolbar.class);
-						if (friendsToolbar != null) {
-							friendsToolbar.addBuddy();
-						}
-					}
-				});
 	}
 
 	//====================================
diff --git a/com/aelitis/azureus/ui/swt/shells/main/MainWindow.java b/com/aelitis/azureus/ui/swt/shells/main/MainWindow.java
index 6fbe512..fe287f0 100644
--- a/com/aelitis/azureus/ui/swt/shells/main/MainWindow.java
+++ b/com/aelitis/azureus/ui/swt/shells/main/MainWindow.java
@@ -43,8 +43,6 @@ import org.gudy.azureus2.core3.torrent.TOTorrentException;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.core3.util.Constants;
 
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.ui.sidebar.SideBarEntry;
 import org.gudy.azureus2.plugins.ui.sidebar.SideBarOpenListener;
 import org.gudy.azureus2.ui.swt.*;
@@ -62,13 +60,9 @@ import org.gudy.azureus2.ui.swt.shells.MessageSlideShell;
 import org.gudy.azureus2.ui.swt.views.IView;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
-import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils.RunDownloadManager;
 import org.gudy.azureus2.ui.systray.SystemTraySWT;
 
 import com.aelitis.azureus.activities.VuzeActivitiesManager;
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.VuzeBuddyCreator;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
@@ -78,22 +72,15 @@ import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
 import com.aelitis.azureus.core.messenger.browser.BrowserMessageDispatcher;
 import com.aelitis.azureus.core.messenger.config.*;
 import com.aelitis.azureus.core.messenger.config.PlatformConfigMessenger.PlatformLoginCompleteListener;
-import com.aelitis.azureus.core.torrent.GlobalRatingUtils;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.core.versioncheck.VersionCheckClient;
 import com.aelitis.azureus.launcher.Launcher;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.plugins.startstoprules.defaultplugin.StartStopRulesDefaultPlugin;
-import com.aelitis.azureus.plugins.startstoprules.defaultplugin.StartStopRulesFPListener;
 import com.aelitis.azureus.ui.IUIIntializer;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
-import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.skin.SkinConstants;
 import com.aelitis.azureus.ui.swt.*;
 import com.aelitis.azureus.ui.swt.Initializer;
-import com.aelitis.azureus.ui.swt.buddy.impl.VuzeBuddyFakeSWTImpl;
-import com.aelitis.azureus.ui.swt.buddy.impl.VuzeBuddySWTImpl;
 import com.aelitis.azureus.ui.swt.columns.utils.TableColumnCreatorV3;
 import com.aelitis.azureus.ui.swt.extlistener.StimulusRPC;
 import com.aelitis.azureus.ui.swt.skin.*;
@@ -191,23 +178,6 @@ public class MainWindow
 
 		disposedOrDisposing = false;
 
-		VuzeBuddyManager.init(new VuzeBuddyCreator() {
-			public VuzeBuddy createBuddy(String publicKey) {
-				VuzeBuddyManager.log("created buddy: " + publicKey);
-				return new VuzeBuddySWTImpl(publicKey);
-			}
-
-			public VuzeBuddy createBuddy() {
-				VuzeBuddyManager.log("created buddy");
-				return new VuzeBuddySWTImpl();
-			}
-
-			// @see com.aelitis.azureus.buddy.VuzeBuddyCreator#createPotentialBuddy(Map)
-			public VuzeBuddy createPotentialBuddy(Map map) {
-				return new VuzeBuddyFakeSWTImpl(map);
-			}
-		});
-
 		// Hack for 3014 -> 3016 upgrades on Vista who become an Administrator
 		// user after restart.
 		if (Constants.isWindows
@@ -230,11 +200,13 @@ public class MainWindow
 						fos.close();
 
 						COConfigurationManager.setParameter("vista.adminquit", true);
-						MessageBoxShell.open(shell,
+						MessageBoxShell mb = new MessageBoxShell(
 								MessageText.getString("mb.azmustclose.title"),
 								MessageText.getString("mb.azmustclose.text"), new String[] {
 									MessageText.getString("Button.ok")
 								}, 0);
+						mb.open(null);
+						mb.waitUntilClosed();
 						if (uiInitializer != null) {
 							uiInitializer.abortProgress();
 						}
@@ -293,40 +265,7 @@ public class MainWindow
 
 					throws GlobalManagerDownloadRemovalVetoException {
 				TOTorrent torrent = dm.getTorrent();
-				if (PublishUtils.isPublished(dm)) {
-					String title = MessageText.getString("v3.mb.delPublished.title");
-
-					ContentNetwork cn = DataSourceUtils.getContentNetwork(torrent);
-					if (cn == null) {
-						return;
-					}
-
-					String site = ContentNetworkUtils.getUrl(cn,
-							ContentNetwork.SERVICE_SITE);
-
-					String site_host = (String) cn.getProperty(ContentNetwork.PROPERTY_SITE_HOST);
-
-					String text = MessageText.getString("v3.mb.delPublished.text",
-							new String[] {
-								dm.getDisplayName(),
-								site,
-								site_host,
-								ContentNetworkUtils.getUrl(cn,
-										ContentNetwork.SERVICE_PUBLISH_ABOUT)
-							});
-
-					MessageBoxShell mb = new MessageBoxShell(shell, title, text,
-							new String[] {
-								MessageText.getString("v3.mb.delPublished.delete"),
-								MessageText.getString("v3.mb.delPublished.cancel")
-							}, 1);
-					mb.setRelatedObject(dm);
-
-					int result = mb.open();
-					if (result != 0) {
-						throw new GlobalManagerDownloadRemovalVetoException("", true);
-					}
-				} else if (PlatformTorrentUtils.isContentDRM(torrent) && remove_data) {
+				if (PlatformTorrentUtils.isContentDRM(torrent) && remove_data) {
 
 					String prefix = "v3.mb.deletePurchased.";
 					String title = MessageText.getString(prefix + "title");
@@ -334,14 +273,15 @@ public class MainWindow
 						dm.getDisplayName()
 					});
 
-					MessageBoxShell mb = new MessageBoxShell(shell, title, text,
+					MessageBoxShell mb = new MessageBoxShell(title, text,
 							new String[] {
 								MessageText.getString(prefix + "button.delete"),
 								MessageText.getString(prefix + "button.cancel")
 							}, 1);
 					mb.setRelatedObject(dm);
 
-					int result = mb.open();
+					mb.open(null);
+					int result = mb.waitUntilClosed();
 					if (result != 0) {
 						throw new GlobalManagerDownloadRemovalVetoException("", true);
 					}
@@ -428,23 +368,6 @@ public class MainWindow
 			uiFunctions.showGlobalTransferBar();
 		}
 
-		VuzeBuddyManager.init(new VuzeBuddyCreator() {
-			public VuzeBuddy createBuddy(String publicKey) {
-				VuzeBuddyManager.log("created buddy: " + publicKey);
-				return new VuzeBuddySWTImpl(publicKey);
-			}
-
-			public VuzeBuddy createBuddy() {
-				VuzeBuddyManager.log("created buddy");
-				return new VuzeBuddySWTImpl();
-			}
-
-			// @see com.aelitis.azureus.buddy.VuzeBuddyCreator#createPotentialBuddy(Map)
-			public VuzeBuddy createPotentialBuddy(Map map) {
-				return new VuzeBuddyFakeSWTImpl(map);
-			}
-		});
-
 		// Hack for 3014 -> 3016 upgrades on Vista who become an Administrator
 		// user after restart.
 		if (Constants.isWindows
@@ -467,11 +390,13 @@ public class MainWindow
 						fos.close();
 
 						COConfigurationManager.setParameter("vista.adminquit", true);
-						MessageBoxShell.open(shell,
+						MessageBoxShell mb = new MessageBoxShell(
 								MessageText.getString("mb.azmustclose.title"),
 								MessageText.getString("mb.azmustclose.text"), new String[] {
 									MessageText.getString("Button.ok")
 								}, 0);
+						mb.open(null);
+						mb.waitUntilClosed();
 						if (uiInitializer != null) {
 							uiInitializer.abortProgress();
 						}
@@ -483,34 +408,11 @@ public class MainWindow
 			}
 		}
 
-		try {
-			DCAdManager.getInstance().initialize(core);
-		} catch (Throwable e) {
-		}
-
 		StimulusRPC.hookListeners(core, this);
 
 		uiSWTInstanceImpl = new UISWTInstanceImpl(core);
 		uiSWTInstanceImpl.init(uiInitializer);
 
-		PluginInterface pi = core.getPluginManager().getPluginInterfaceByID(
-				"azbpstartstoprules");
-		if (pi != null) {
-			// plugin is built in, so instead of using IPC, just cast it
-			StartStopRulesDefaultPlugin plugin = (StartStopRulesDefaultPlugin) pi.getPlugin();
-			plugin.addListener(new StartStopRulesFPListener() {
-				public boolean isFirstPriority(Download dl, int numSeeds, int numPeers,
-						StringBuffer debug) {
-					// FP while our content doesn't have another seed
-					boolean b = dl.getState() == Download.ST_SEEDING && numSeeds == 0
-							&& dl.getStats().getAvailability() < 2
-							&& PublishUtils.isPublished(dl); // do last as most costly
-
-					return b;
-				}
-			});
-		}
-
 		VuzeActivitiesManager.initialize(core);
 
 		// When a download is added, check for new meta data and
@@ -547,40 +449,7 @@ public class MainWindow
 
 					throws GlobalManagerDownloadRemovalVetoException {
 				TOTorrent torrent = dm.getTorrent();
-				if (PublishUtils.isPublished(dm)) {
-					String title = MessageText.getString("v3.mb.delPublished.title");
-
-					ContentNetwork cn = DataSourceUtils.getContentNetwork(torrent);
-					if (cn == null) {
-						return;
-					}
-
-					String site = ContentNetworkUtils.getUrl(cn,
-							ContentNetwork.SERVICE_SITE);
-
-					String site_host = (String) cn.getProperty(ContentNetwork.PROPERTY_SITE_HOST);
-
-					String text = MessageText.getString("v3.mb.delPublished.text",
-							new String[] {
-								dm.getDisplayName(),
-								site,
-								site_host,
-								ContentNetworkUtils.getUrl(cn,
-										ContentNetwork.SERVICE_PUBLISH_ABOUT)
-							});
-
-					MessageBoxShell mb = new MessageBoxShell(shell, title, text,
-							new String[] {
-								MessageText.getString("v3.mb.delPublished.delete"),
-								MessageText.getString("v3.mb.delPublished.cancel")
-							}, 1);
-					mb.setRelatedObject(dm);
-
-					int result = mb.open();
-					if (result != 0) {
-						throw new GlobalManagerDownloadRemovalVetoException("", true);
-					}
-				} else if (PlatformTorrentUtils.isContentDRM(torrent) && remove_data) {
+				if (PlatformTorrentUtils.isContentDRM(torrent) && remove_data) {
 
 					String prefix = "v3.mb.deletePurchased.";
 					String title = MessageText.getString(prefix + "title");
@@ -588,14 +457,15 @@ public class MainWindow
 						dm.getDisplayName()
 					});
 
-					MessageBoxShell mb = new MessageBoxShell(shell, title, text,
+					MessageBoxShell mb = new MessageBoxShell(title, text,
 							new String[] {
 								MessageText.getString(prefix + "button.delete"),
 								MessageText.getString(prefix + "button.cancel")
 							}, 1);
 					mb.setRelatedObject(dm);
 
-					int result = mb.open();
+					mb.open(null);
+					int result = mb.waitUntilClosed();
 					if (result != 0) {
 						throw new GlobalManagerDownloadRemovalVetoException("", true);
 					}
@@ -658,7 +528,6 @@ public class MainWindow
 	}
 
 	private void downloadAdded(final DownloadManager[] dms) {
-		ArrayList<TOTorrent> toUpdateGlobalRating = new ArrayList();
 		boolean oneIsNotPlatform = false;
 		for (final DownloadManager dm : dms) {
 			if (dm == null) {
@@ -696,7 +565,8 @@ public class MainWindow
 				}
 			}
 
-			boolean isContent = PlatformTorrentUtils.isContent(torrent, true);
+			boolean isContent = PlatformTorrentUtils.isContent(torrent, true)
+					|| PlatformTorrentUtils.getContentNetworkID(torrent) == ContentNetwork.CONTENT_NETWORK_VHDNL;
 
 			if (!oneIsNotPlatform && !isContent
 					&& !dmState.getFlag(DownloadManagerState.FLAG_LOW_NOISE)) {
@@ -706,43 +576,7 @@ public class MainWindow
 			final String fHash = hash;
 
 			if (isContent) {
-				if (PlatformTorrentUtils.getUserRating(torrent) == -2) {
-					PlatformTorrentUtils.setUserRating(torrent, -1);
-					PlatformRatingMessenger.getUserRating(
-							PlatformTorrentUtils.getContentNetworkID(torrent), new String[] {
-								PlatformRatingMessenger.RATE_TYPE_CONTENT
-							}, new String[] {
-								hash
-							}, 5000);
-				}
-
 				long now = SystemTime.getCurrentTime();
-				long mdRefreshOn = PlatformTorrentUtils.getMetaDataRefreshOn(torrent);
-				if (mdRefreshOn < now) {
-					PlatformTorrentUtils.log(torrent, "addDM, update MD NOW");
-					PlatformTorrentUtils.updateMetaData(torrent, 5000);
-				} else {
-					PlatformTorrentUtils.log(torrent, "addDM, update MD on "
-							+ new Date(mdRefreshOn));
-					SimpleTimer.addEvent("Update MD", mdRefreshOn,
-							new TimerEventPerformer() {
-								public void perform(TimerEvent event) {
-									PlatformTorrentUtils.updateMetaData(torrent, 15000);
-								}
-							});
-				}
-
-				long grRefreshOn = GlobalRatingUtils.getRefreshOn(torrent);
-				if (grRefreshOn <= now) {
-					toUpdateGlobalRating.add(torrent);
-				} else {
-					SimpleTimer.addEvent("Update G.Rating", grRefreshOn,
-							new TimerEventPerformer() {
-								public void perform(TimerEvent event) {
-									PlatformRatingMessenger.updateGlobalRating(torrent, 15000);
-								}
-							});
-				}
 
 				long expiresOn = PlatformTorrentUtils.getExpiresOn(torrent);
 				if (expiresOn > now) {
@@ -755,22 +589,12 @@ public class MainWindow
 								}
 							});
 				}
-
-				if (PublishUtils.isPublished(dm)
-						&& dm.getStats().getShareRatio() < 1000 && !dm.isForceStart()) {
-					dm.setForceStart(true);
-				}
 			} // isContent
 		}
 
 		if (oneIsNotPlatform && dms_Startup == null) {
 			DonationWindow.checkForDonationPopup();
 		}
-
-		if (toUpdateGlobalRating.size() > 0) {
-			TOTorrent[] torrents = toUpdateGlobalRating.toArray(new TOTorrent[0]);
-			PlatformRatingMessenger.updateGlobalRating(torrents, 5000);
-		}
 	}
 
 	/**
@@ -868,22 +692,47 @@ public class MainWindow
 					+ (SystemTime.getCurrentTime() - startTime) + "ms");
 			startTime = SystemTime.getCurrentTime();
 
-			if (org.gudy.azureus2.core3.util.Constants.isOSX
-					&& SWT.getPlatform().equals("carbon")) {
-				try {
+			if (Constants.isOSX) {
+				if (Utils.isCarbon) {
+  				try {
+  
+  					Class<?> ehancerClass = Class.forName("org.gudy.azureus2.ui.swt.osx.CarbonUIEnhancer");
+  
+  					Method method = ehancerClass.getMethod("registerToolbarToggle",
+  							new Class[] {
+  								Shell.class
+  							});
+  					method.invoke(null, new Object[] {
+  						shell
+  					});
+  
+  				} catch (Exception e) {
+  					Debug.printStackTrace(e);
+  				}
+				} else if (Utils.isCocoa) {
+					try {
 
-					Class ehancerClass = Class.forName("org.gudy.azureus2.ui.swt.osx.CarbonUIEnhancer");
+						Class<?> ehancerClass = Class.forName("org.gudy.azureus2.ui.swt.osx.CocoaUIEnhancer");
 
-					Method method = ehancerClass.getMethod("registerToolbarToggle",
-							new Class[] {
-								Shell.class
+						Method mGetInstance = ehancerClass.getMethod("getInstance",
+								new Class[0]);
+						Object claObj = mGetInstance.invoke(null, new Object[0]);
+
+						Method mregTBToggle = claObj.getClass().getMethod(
+								"registerToolbarToggle", new Class[] {
+									Shell.class
+								});
+						if (mregTBToggle != null) {
+							mregTBToggle.invoke(claObj, new Object[] {
+								shell
 							});
-					method.invoke(null, new Object[] {
-						shell
-					});
+						}
+
+					} catch (Throwable e) {
+
+						Debug.printStackTrace(e);
+					}
 
-				} catch (Exception e) {
-					Debug.printStackTrace(e);
 				}
 
 				Listener toggleListener = new Listener() {
@@ -937,6 +786,15 @@ public class MainWindow
 					}
 				}
 
+				public void shellActivated(ShellEvent e) {
+					Shell shellAppModal = Utils.findFirstShellWithStyle(SWT.APPLICATION_MODAL);
+					if (shellAppModal != null) {
+						shellAppModal.forceActive();
+					} else {
+						shell.forceActive();
+					}
+				}
+
 				public void shellIconified(ShellEvent event) {
 					if (disposedOrDisposing) {
 						return;
@@ -966,11 +824,6 @@ public class MainWindow
 			startTime = SystemTime.getCurrentTime();
 
 			if (core != null) {
-				try {
-					DCAdManager.getInstance().initialize(core);
-				} catch (Throwable e) {
-				}
-
 				StimulusRPC.hookListeners(core, this);
 			}
 
@@ -1030,37 +883,6 @@ public class MainWindow
 			increaseProgress(uiInitializer, "splash.initializeGui");
 			startTime = SystemTime.getCurrentTime();
 
-			if (core != null) {
-				PluginInterface pi = core.getPluginManager().getPluginInterfaceByID(
-						"azbpstartstoprules");
-				if (pi != null) {
-					// plugin is built in, so instead of using IPC, just cast it
-					StartStopRulesDefaultPlugin plugin = (StartStopRulesDefaultPlugin) pi.getPlugin();
-					plugin.addListener(new StartStopRulesFPListener() {
-						public boolean isFirstPriority(Download dl, int numSeeds,
-								int numPeers, StringBuffer debug) {
-							// FP while our content doesn't have another seed
-							boolean b = dl.getState() == Download.ST_SEEDING && numSeeds == 0
-									&& dl.getStats().getAvailability() < 2
-									&& PublishUtils.isPublished(dl); // do last as most costly
-
-							return b;
-						}
-					});
-				}
-			}
-
-			ManagerUtils.setRunRunnable(new RunDownloadManager() {
-				public void run(DownloadManager dm) {
-					TOTorrent torrent = dm.getTorrent();
-					if (PlatformTorrentUtils.isContent(torrent, true)
-							&& PlatformTorrentUtils.isContentAdEnabled(torrent)) {
-						TorrentListViewsUtils.playOrStream(dm);
-					} else {
-						Utils.launch(dm.getSaveLocation().toString());
-					}
-				}
-			});
 		} catch (Throwable t) {
 			Debug.out(t);
 		} finally {
@@ -1074,12 +896,6 @@ public class MainWindow
 					COConfigurationManager.getBooleanParameter(configID)
 							&& COConfigurationManager.getIntParameter("User Mode") > 1);
 
-			configID = "Friends.visible";
-			if (false == ConfigurationDefaults.getInstance().doesParameterDefaultExist(
-					configID)) {
-				COConfigurationManager.setBooleanDefault(configID, true);
-			}
-
 			setVisible(WINDOW_ELEMENT_TABBAR, true);
 
 			shell.layout(true, true);
@@ -1131,32 +947,7 @@ public class MainWindow
 
 									uif.bringToFront();
 								}
-							} else if (type == NavigationHelper.COMMAND_BUDDY_SYNC) {
-
-								try {
-									PlatformRelayMessenger.fetch(0);
-									PlatformBuddyMessenger.sync(null);
-									PlatformBuddyMessenger.getInvites();
-								} catch (NotLoggedInException e1) {
-								}
-
 							} else if (type == NavigationHelper.COMMAND_CONDITION_CHECK) {
-
-								if (args[0].equals(NavigationHelper.COMMAND_CHECK_BUDDY_MANAGER)) {
-
-									if (args[1].equals(NavigationHelper.COMMAND_CHECK_BUDDY_MANAGER_ENABLED)) {
-
-										if (!VuzeBuddyManager.isEnabled()) {
-
-											VuzeBuddyManager.showDisabledDialog();
-
-											if (uif != null) {
-
-												uif.bringToFront();
-											}
-										}
-									}
-								}
 							}
 						}
 					});
@@ -1177,31 +968,38 @@ public class MainWindow
 
 		Utils.execSWTThreadLater(0, new AERunnable() {
 			public void runSupport() {
+				final String CFG_STARTTAB = "v3.StartTab";
 				String startTab;
 				boolean showWelcome = COConfigurationManager.getBooleanParameter("v3.Show Welcome");
-				boolean startAdv = COConfigurationManager.getBooleanParameter("v3.Start Advanced");
 
 				ContentNetwork startupCN = ContentNetworkManagerFactory.getSingleton().getStartupContentNetwork();
 				if (!startupCN.isServiceSupported(ContentNetwork.SERVICE_WELCOME)) {
 					showWelcome = false;
 				}
 
-				if (showWelcome && !startAdv) {
+				if (showWelcome) {
 					startTab = SideBar.SIDEBAR_SECTION_WELCOME;
 				} else {
-					if (showWelcome && startAdv) {
-						sidebar.showEntryByID(SideBar.SIDEBAR_SECTION_WELCOME);
+					if (!COConfigurationManager.hasParameter(CFG_STARTTAB, true)) {
+						COConfigurationManager.setParameter(CFG_STARTTAB,
+								SideBar.SIDEBAR_SECTION_LIBRARY);
 					}
-					if (COConfigurationManager.getBooleanParameter("v3.Start Advanced")) {
+					startTab = COConfigurationManager.getStringParameter(CFG_STARTTAB);
+					if (!SideBar.entryExists(startTab)) {
 						startTab = SideBar.SIDEBAR_SECTION_LIBRARY;
-					} else {
-						startTab = "ContentNetwork." + startupCN.getID();
-						ContentNetworkUtils.setSourceRef(startTab, "startup", false);
 					}
 				}
 				sidebar.showEntryByTabID(startTab);
 			}
 		});
+		
+		sidebar.addListener(new SideBarListener() {
+			public void sidebarItemSelected(SideBarEntrySWT newSideBarEntry,
+					SideBarEntrySWT oldSideBarEntry) {
+				COConfigurationManager.setParameter("v3.StartTab",
+						newSideBarEntry.getId());
+			}
+		});
 
 		//		System.out.println("Activate sidebar " + startTab + " took "
 		//				+ (SystemTime.getCurrentTime() - startTime) + "ms");
@@ -1462,9 +1260,7 @@ public class MainWindow
 		}
 
 		boolean isOSX = org.gudy.azureus2.core3.util.Constants.isOSX;
-		// No tray access on OSX yet
-		boolean bEnableTray = COConfigurationManager.getBooleanParameter("Enable System Tray")
-				&& (!isOSX || SWT.getVersion() > 3300);
+		boolean bEnableTray = COConfigurationManager.getBooleanParameter("Enable System Tray");
 		boolean bPassworded = COConfigurationManager.getBooleanParameter("Password enabled");
 		boolean bStartMinimize = bEnableTray
 				&& (bPassworded || COConfigurationManager.getBooleanParameter("Start Minimized"));
@@ -1494,9 +1290,14 @@ public class MainWindow
 		
 
 		if (delayedCore) {
-			// TODO: Check if update window takes control and messes things up
-  		while (!display.isDisposed() && display.readAndDispatch());
-  		System.out.println("---------DONE DISPATCH AT "
+			// max 5 seconds of dispatching.  We don't display.sleep here because
+			// we only want to clear the backlog of SWT events, and sleep would
+			// add new ones
+			long endSWTDispatchOn = SystemTime.getOffsetTime(5000);
+			while (SystemTime.getCurrentTime() < endSWTDispatchOn
+					&& !display.isDisposed() && display.readAndDispatch());
+
+			System.out.println("---------DONE DISPATCH AT "
   				+ SystemTime.getCurrentTime() + ";"
   				+ (SystemTime.getCurrentTime() - Initializer.startTime) + "ms");
   		if (display.isDisposed()) {
@@ -1511,6 +1312,7 @@ public class MainWindow
 
 			} catch (Throwable e) {
 
+				e.printStackTrace();
 				Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
 						"Upgrade to SWT3.0M8 or later for system tray support."));
 			}
@@ -1598,7 +1400,9 @@ public class MainWindow
 				}
 
 				if (visible) {
-					shell.setMinimized(false);
+					if (shell.getMinimized()) {
+						shell.setMinimized(false);
+					}
 					if (!currentlyVisible
 							&& COConfigurationManager.getBooleanParameter("window.maximized")) {
 						shell.setMaximized(true);
@@ -1816,14 +1620,10 @@ public class MainWindow
 		 * before it's even shown for the first time
 		 */
 		Class[] forceInits = new Class[] {
-			BuddiesViewer.class,
 			SideBar.class,
-			FriendsToolbar.class
 		};
 		String[] forceInitsIDs = new String[] {
-			SkinConstants.VIEWID_BUDDIES_VIEWER,
 			SkinConstants.VIEWID_SIDEBAR,
-			SkinConstants.VIEWID_FRIENDS_TOOLBAR
 		};
 
 		for (int i = 0; i < forceInits.length; i++) {
@@ -1903,11 +1703,6 @@ public class MainWindow
 						topbarMenu);
 			}
 		}
-
-		/*
-		 * Init the user area for login/logout info
-		 */
-		new UserAreaUtils(skin, uiFunctions);
 	}
 
 	private void addMenuAndNonTextChildren(Composite parent, Menu menu) {
@@ -2115,7 +1910,7 @@ public class MainWindow
 		if (fd == null || fd.width <= 0) {
 			return;
 		}
-		if (clientArea.width > 1024 && fd.width == 260) {
+		if (clientArea.width > 1024 && fd.width == 195) {
 			return;
 		}
 		SWTSkinObject soTabBar = skin.getSkinObject(SkinConstants.VIEWID_TAB_BAR);
@@ -2127,8 +1922,8 @@ public class MainWindow
 		fd.width = clientArea.width - (size.x - oldWidth) - 5;
 		if (fd.width < 100) {
 			fd.width = 100;
-		} else if (fd.width > 260) {
-			fd.width = 260;
+		} else if (fd.width > 195) {
+			fd.width = 195;
 		}
 
 		if (oldWidth != fd.width) {
diff --git a/com/aelitis/azureus/ui/swt/shells/main/UIFunctionsImpl.java b/com/aelitis/azureus/ui/swt/shells/main/UIFunctionsImpl.java
index a782a49..a4401bb 100644
--- a/com/aelitis/azureus/ui/swt/shells/main/UIFunctionsImpl.java
+++ b/com/aelitis/azureus/ui/swt/shells/main/UIFunctionsImpl.java
@@ -52,6 +52,7 @@ import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.update.FullUpdateWindow;
 import org.gudy.azureus2.ui.swt.views.*;
+import org.gudy.azureus2.ui.swt.views.clientstats.ClientStatsView;
 import org.gudy.azureus2.ui.swt.views.stats.StatsView;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
 
@@ -59,9 +60,7 @@ import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.ui.InitializerListener;
-import com.aelitis.azureus.ui.UIFunctionsUserPrompter;
-import com.aelitis.azureus.ui.UIStatusTextClickListener;
+import com.aelitis.azureus.ui.*;
 import com.aelitis.azureus.ui.common.updater.UIUpdater;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 import com.aelitis.azureus.ui.swt.Initializer;
@@ -502,7 +501,15 @@ public class UIFunctionsImpl
 		return false;
 	}
 
-	public void openView(int viewID, Object data) {
+	public void openView(final int viewID, final Object data) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				_openView(viewID, data);
+			}
+		});
+	}
+		
+	private void _openView(int viewID, Object data) {
 		if (mainWindow.isOnAdvancedView()) {
 			UIFunctionsSWT uiFunctions = mainWindow.getOldUIFunctions(false);
 			if (uiFunctions != null) {
@@ -522,6 +529,11 @@ public class UIFunctionsImpl
 						null, data, true);
 				break;
 
+			case VIEW_PEERS_STATS:
+				mainWindow.openView(SideBar.SIDEBAR_SECTION_TOOLS, ClientStatsView.class,
+						null, data, true);
+				break;
+
 			case VIEW_CONFIG:
 				showConfig((data instanceof String) ? (String) data : null);
 				break;
@@ -670,20 +682,20 @@ public class UIFunctionsImpl
 	}
 
 	// @see com.aelitis.azureus.ui.UIFunctions#promptUser(java.lang.String, java.lang.String, java.lang.String[], int, java.lang.String, java.lang.String, boolean, int)
-	public int promptUser(String title, String text, String[] buttons,
+	public void promptUser(String title, String text, String[] buttons,
 			int defaultOption, String rememberID, String rememberText,
-			boolean rememberByDefault, int autoCloseInMS) {
-		return MessageBoxShell.open(getMainShell(), title, text, buttons,
+			boolean rememberByDefault, int autoCloseInMS, UserPrompterResultListener l) {
+		MessageBoxShell.open(getMainShell(), title, text, buttons,
 				defaultOption, rememberID, rememberText, rememberByDefault,
-				autoCloseInMS);
+				autoCloseInMS, l);
 	}
 
 	// @see com.aelitis.azureus.ui.UIFunctions#getUserPrompter(java.lang.String, java.lang.String, java.lang.String[], int)
 	public UIFunctionsUserPrompter getUserPrompter(String title, String text,
 			String[] buttons, int defaultOption) {
 
-		MessageBoxShell mb = new MessageBoxShell(getMainShell(), title, text,
-				buttons, defaultOption);
+		MessageBoxShell mb = new MessageBoxShell(title, text, buttons,
+				defaultOption);
 		return mb;
 	}
 
@@ -853,13 +865,13 @@ public class UIFunctionsImpl
 				public void paintControl(PaintEvent e) {
 					Control c = (Control) e.widget;
 					Point size = c.getSize();
-					e.gc.setBackground(ColorCache.getColor(e.display, "#0000ff"));
+					e.gc.setBackground(ColorCache.getColor(e.display, "#23a7df"));
 					Object data = soWaitProgress.getData("progress");
 					if (data instanceof Long) {
 						int waitProgress = ((Long) data).intValue();
 						int breakX = size.x * waitProgress / 100;
 						e.gc.fillRectangle(0, 0, breakX, size.y);
-						e.gc.setBackground(ColorCache.getColor(e.display, "#808080"));
+						e.gc.setBackground(ColorCache.getColor(e.display, "#cccccc"));
 						e.gc.fillRectangle(breakX, 0, size.x - breakX, size.y);
 					}
 				}
diff --git a/com/aelitis/azureus/ui/swt/shells/uiswitcher/UISwitcherWindow.java b/com/aelitis/azureus/ui/swt/shells/uiswitcher/UISwitcherWindow.java
index 5d1e558..ca885e4 100644
--- a/com/aelitis/azureus/ui/swt/shells/uiswitcher/UISwitcherWindow.java
+++ b/com/aelitis/azureus/ui/swt/shells/uiswitcher/UISwitcherWindow.java
@@ -31,8 +31,10 @@ import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.*;
 
+import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.UISwitcherUtil;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 
@@ -74,6 +76,7 @@ public class UISwitcherWindow
 	 * 
 	 */
 	public UISwitcherWindow(Shell parentShell, final boolean allowCancel) {
+		final String originalUIMode = UISwitcherUtil.calcUIMode();
 		try {
 			final Image[] images = new Image[IMAGES.length];
 			final Button[] buttons = new Button[IMAGES.length];
@@ -90,6 +93,17 @@ public class UISwitcherWindow
 			shell.addDisposeListener(new DisposeListener() {
 				public void widgetDisposed(DisposeEvent e) {
 					Utils.disposeSWTObjects(disposeList);
+					if (ui == 0) {
+						// Full AZ3UI
+						COConfigurationManager.setParameter("ui", "az3");
+					} else if (ui == 1) {
+						COConfigurationManager.setParameter("ui", "az2");
+					}
+
+					if (ui != -1) {
+						COConfigurationManager.setParameter("ui.asked", true);
+						UISwitcherUtil.triggerListeners(UISwitcherUtil.calcUIMode());
+					}
 				}
 			});
 
@@ -288,20 +302,19 @@ public class UISwitcherWindow
 		}
 	}
 
-	public int open() {
+	public void open() {
 		shell.open();
+	}
 
+	public static void main(String[] args) {
+		Display display = Display.getDefault();
+		UISwitcherWindow window = new UISwitcherWindow(null, false);
+		Shell shell = window.shell;
 		while (!shell.isDisposed()) {
 			if (!shell.getDisplay().readAndDispatch()) {
 				shell.getDisplay().sleep();
 			}
 		}
-		return ui;
-	}
-
-	public static void main(String[] args) {
-		Display display = Display.getDefault();
-		UISwitcherWindow window = new UISwitcherWindow(null, false);
-		System.out.println(window.open());
+		System.out.println(window.ui);
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkin.java b/com/aelitis/azureus/ui/swt/skin/SWTSkin.java
index b6a4626..7cde2b2 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkin.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkin.java
@@ -495,12 +495,16 @@ public class SWTSkin
 				Control cursorControl = shell.getDisplay().getCursorControl();
 				//System.out.println("move from " + (lastControl == null ? null : lastControl.handle) + " to " + (cursorControl == null ? "null" : cursorControl.handle));
 				if (cursorControl != lastControl) {
+					Point cursorLocation = shell.getDisplay().getCursorLocation();
 					while (lastControl != null && !lastControl.isDisposed()) {
-						SWTSkinObjectBasic so = (SWTSkinObjectBasic) lastControl.getData("SkinObject");
-						if (so != null) {
-							so.switchSuffix("", 3, false, false);
+						Point cursorLocationInControl = lastControl.toControl(cursorLocation);
+						Point size = lastControl.getSize();
+						if (!new Rectangle(0, 0, size.x, size.y).contains(cursorLocationInControl)) {
+  						SWTSkinObjectBasic so = (SWTSkinObjectBasic) lastControl.getData("SkinObject");
+  						if (so != null) {
+  							so.switchSuffix("", 3, false, false);
+  						}
 						}
-
 						lastControl = lastControl.getParent();
 					}
 					lastControl = cursorControl;
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBasic.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBasic.java
index 47b9644..8114d38 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBasic.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBasic.java
@@ -194,7 +194,7 @@ public class SWTSkinObjectBasic
 		control.setData("SkinObject", this);
 
 		SWTSkinUtils.addMouseImageChangeListeners(control);
-		switchSuffix("", 1, false);
+		switchSuffix(null, 0, false);
 
 		// setvisible is one time only
 		if (!properties.getBooleanValue(sConfigID + ".visible", true)) {
@@ -496,7 +496,7 @@ public class SWTSkinObjectBasic
 		return switchSuffix(suffix, level, walkUp, true);
 	}
 
-	public String switchSuffix(String suffix, int level, boolean walkUp, boolean walkDown) {
+	public String switchSuffix(String newSuffixEntry, int level, boolean walkUp, boolean walkDown) {
 		if (walkUp) {
 			SWTSkinObject parentSkinObject = parent;
 			SWTSkinObject skinObject = this;
@@ -511,30 +511,35 @@ public class SWTSkinObjectBasic
 			if (skinObject != this) {
 				//System.out.println(sConfigID + suffix + "; walkup");
 
-				skinObject.switchSuffix(suffix, level, false);
+				skinObject.switchSuffix(newSuffixEntry, level, false);
 				return null;
 			}
 		}
+		String old = getSuffix();
 
 		if (level > 0) {
   		//System.out.println(SystemTime.getCurrentTime() + ": " + this + suffix + "; switchy");
   		if (suffixes == null) {
+  			old = null;
   			suffixes = new String[level];
   		} else if (suffixes.length < level) {
   			String[] newSuffixes = new String[level];
   			System.arraycopy(suffixes, 0, newSuffixes, 0, suffixes.length);
   			suffixes = newSuffixes;
   		}
-  		suffixes[level - 1] = suffix;
+  		suffixes[level - 1] = newSuffixEntry;
 		}
 
-		suffix = getSuffix();
+		String fullSuffix = getSuffix();
 
-		if (sConfigID == null || control == null || control.isDisposed() || !isVisible) {
-			return suffix;
+		if (newSuffixEntry != null) {
+  		if (sConfigID == null || control == null || control.isDisposed()
+  				|| !isVisible || (newSuffixEntry != null && fullSuffix.equals(old))) {
+  			return fullSuffix;
+  		}
 		}
 
-		final String sSuffix = suffix;
+		final String sSuffix = fullSuffix;
 
 		Utils.execSWTThread(new AERunnable() {
 
@@ -657,11 +662,14 @@ public class SWTSkinObjectBasic
 			}
 
 		});
-		return suffix;
+		return fullSuffix;
 	}
 
 	public String getSuffix() {
 		String suffix = "";
+		if (suffixes == null) {
+			return suffix;
+		}
 		for (int i = 0; i < suffixes.length; i++) {
 			if (suffixes[i] != null) {
 				suffix += suffixes[i];
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBrowser.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBrowser.java
index e83a330..f952a88 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBrowser.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBrowser.java
@@ -20,18 +20,14 @@
 
 package com.aelitis.azureus.ui.swt.skin;
 
-import java.io.File;
-import java.net.URL;
-
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.SWTError;
 import org.eclipse.swt.browser.Browser;
 import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.*;
 
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.ui.swt.Utils;
 
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
@@ -40,10 +36,6 @@ import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 import com.aelitis.azureus.ui.swt.browser.BrowserContext;
 import com.aelitis.azureus.ui.swt.browser.BrowserContext.loadingListener;
 import com.aelitis.azureus.ui.swt.browser.listener.*;
-import com.aelitis.azureus.ui.swt.browser.listener.publish.LocalHoster;
-import com.aelitis.azureus.ui.swt.browser.listener.publish.PublishListener;
-import com.aelitis.azureus.ui.swt.utils.PublishUtils;
-import com.aelitis.azureus.util.LocalResourceHTTPServer;
 import com.aelitis.azureus.util.UrlFilter;
 
 /**
@@ -53,7 +45,6 @@ import com.aelitis.azureus.util.UrlFilter;
  */
 public class SWTSkinObjectBrowser
 	extends SWTSkinObjectBasic
-	implements LocalHoster
 {
 
 	private Browser browser;
@@ -64,8 +55,6 @@ public class SWTSkinObjectBrowser
 
 	private String sStartURL;
 
-	private LocalResourceHTTPServer local_publisher;
-
 	private BrowserContext context;
 
 	private String urlToUse;
@@ -126,17 +115,6 @@ public class SWTSkinObjectBrowser
 			return;
 		}
 
-		//TODO [SWT] : Remove this stupid code as soon as we update SWT
-		if(Constants.isOSX && ! doneTheUglySWTFocusHack) {
-			doneTheUglySWTFocusHack = true;
-			Shell shell = new Shell(browser.getDisplay(),SWT.NONE);
-			shell.setSize(1,1);
-			shell.setLocation(-2, -2);
-			shell.open();
-			shell.close();
-			browser.setFocus();
-		}
-		
 		Control widgetIndicator = null;
 		String sIndicatorWidgetID = properties.getStringValue(sConfigID
 				+ ".indicator");
@@ -159,10 +137,6 @@ public class SWTSkinObjectBrowser
 		context.addMessageListener(new VuzeListener());
 		context.addMessageListener(new DisplayListener(browser));
 		context.addMessageListener(new ConfigListener(browser));
-		context.addMessageListener(new PublishListener(skin.getShell(), this));
-		context.addMessageListener(new LightBoxBrowserRequestListener());
-		context.addMessageListener(new StatusListener());
-		context.addMessageListener(new BrowserRpcBuddyListener());
 
 		context.addListener(new loadingListener() {
 			public void browserLoadingChanged(boolean loading, String url) {
@@ -176,8 +150,6 @@ public class SWTSkinObjectBrowser
 			}
 		});
 
-		PublishUtils.setupContext(context);
-
 		String url = urlToUse != null ? urlToUse : sStartURL != null ? sStartURL
 				: properties.getStringValue(sConfigID + ".url", (String) null);
 		if (url != null) {
@@ -252,33 +224,6 @@ public class SWTSkinObjectBrowser
 		cParent.layout();
 	}
 	
-	public void dispose() {
-		if (browser != null && !browser.isDisposed()) {
-			browser.setVisible(false);
-			browser.setUrl("about:blank");
-		}
-		super.dispose();
-	}
-
-	// @see com.aelitis.azureus.ui.swt.browser.listener.publish.LocalHoster#hostFile(java.io.File)
-	public URL hostFile(File f) {
-		if (local_publisher == null) {
-			try {
-				PluginInterface pi = PluginInitializer.getDefaultInterface();
-				local_publisher = new LocalResourceHTTPServer(pi, null);
-			} catch (Throwable e) {
-				Debug.out("Failed to create local resource publisher", e);
-				return null;
-			}
-		}
-		try {
-			return local_publisher.publishResource(f);
-		} catch (Exception e) {
-			e.printStackTrace();
-			return null;
-		}
-	}
-
 	public BrowserContext getContext() {
 		return context;
 	}
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectImage.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectImage.java
index 264bdd2..26ce0ad 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectImage.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectImage.java
@@ -35,9 +35,7 @@ public class SWTSkinObjectImage
 
 	protected static final Long DRAW_HCENTER = new Long(5);
 
-	private static boolean ALWAYS_USE_PAINT = true;
-
-	Label label;
+	private Canvas canvas;
 
 	private boolean customImage;
 
@@ -47,32 +45,30 @@ public class SWTSkinObjectImage
 
 	private static PaintListener paintListener;
 
-	private boolean noSetLabelImage = false;
-
 	private int h_align;
 
 	static {
 		paintListener = new PaintListener() {
 			public void paintControl(PaintEvent e) {
-
+				SWTSkinObject so = (SWTSkinObject) e.widget.getData("SkinObject");
 				try {
 					e.gc.setAdvanced(true);
 					e.gc.setInterpolation(SWT.HIGH);
 				} catch (Exception ex) {
 				}
 
-				Label label = (Label) e.widget;
-				Image imgSrc = (Image) label.getData("image");
+				Canvas control = (Canvas) e.widget;
+				Image imgSrc = (Image) control.getData("image");
 				Image imgRight = null;
 				Image imgLeft = null;
 				String idToRelease = null;
 				ImageLoader imageLoader = null;
 
 				if (imgSrc == null) {
-					SWTSkinObjectImage soImage = (SWTSkinObjectImage) label.getData("SkinObject");
+					SWTSkinObjectImage soImage = (SWTSkinObjectImage) control.getData("SkinObject");
 					imageLoader = soImage.getSkin().getImageLoader(
 							soImage.getProperties());
-					String imageID = (String) label.getData("ImageID");
+					String imageID = (String) control.getData("ImageID");
 					if (imageLoader.imageExists(imageID)) {
 						idToRelease = imageID;
 						Image[] images = imageLoader.getImages(imageID);
@@ -88,9 +84,9 @@ public class SWTSkinObjectImage
 					}
 				}
 				Rectangle imgSrcBounds = imgSrc.getBounds();
-				Point size = label.getSize();
+				Point size = control.getSize();
 
-				Long drawMode = (Long) label.getData("drawmode");
+				Long drawMode = (Long) control.getData("drawmode");
 
 				if (drawMode == DRAW_STRETCH) {
 					e.gc.drawImage(imgSrc, 0, 0, imgSrcBounds.width, imgSrcBounds.height,
@@ -111,7 +107,7 @@ public class SWTSkinObjectImage
 					int y1 = size.y;
 
 					if (imgRight == null) {
-						imgRight = (Image) label.getData("image-right");
+						imgRight = (Image) control.getData("image-right");
 					}
 					if (imgRight != null) {
 						int width = imgRight.getBounds().width;
@@ -120,7 +116,7 @@ public class SWTSkinObjectImage
 					}
 
 					if (imgLeft == null) {
-						imgLeft = (Image) label.getData("image-left");
+						imgLeft = (Image) control.getData("image-left");
 					}
 					if (imgLeft != null) {
 						// TODO: Tile down
@@ -154,17 +150,17 @@ public class SWTSkinObjectImage
 	public SWTSkinObjectImage(SWTSkin skin, SWTSkinProperties skinProperties,
 			String sID, String sConfigID, String sImageID, SWTSkinObject parent) {
 		super(skin, skinProperties, sID, sConfigID, "image", parent);
-		setControl(createImageLabel(sConfigID, sImageID));
+		setControl(createImageWidget(sConfigID, sImageID));
 		customImage = false;
 		customImageID = null;
 	}
 
-	private Label createImageLabel(String sConfigID, String sImageID) {
+	private Canvas createImageWidget(String sConfigID, String sImageID) {
 		currentImageID = sImageID;
-		int style = SWT.WRAP;
+		int style = SWT.WRAP | SWT.DOUBLE_BUFFERED;
 
 		String sAlign = properties.getStringValue(sConfigID + ".align");
-		if (sAlign != null) {
+		if (sAlign != null && !Constants.isUnix) {
 			h_align = SWTSkinUtils.getAlignment(sAlign, SWT.NONE);
 			if (h_align != SWT.NONE) {
 				style |= h_align;
@@ -182,18 +178,18 @@ public class SWTSkinObjectImage
 			createOn = (Composite) parent.getControl();
 		}
 
-		label = new Label(createOn, style);
-		label.setData("SkinObject", this);
+		canvas = new Canvas(createOn, style);
+		canvas.setData("SkinObject", this);
 
 		Color color = properties.getColor(sConfigID + ".color");
 		if (color != null) {
-			label.setBackground(color);
+			canvas.setBackground(color);
 		}
 
 		final String sURL = properties.getStringValue(sConfigID + ".url");
 		if (sURL != null && sURL.length() > 0) {
-			label.setToolTipText(sURL);
-			label.addListener(SWT.MouseUp, new Listener() {
+			canvas.setToolTipText(sURL);
+			canvas.addListener(SWT.MouseUp, new Listener() {
 				public void handleEvent(Event arg0) {
 					Utils.launch(UrlUtils.encode(sURL));
 				}
@@ -203,28 +199,31 @@ public class SWTSkinObjectImage
 		String sCursor = properties.getStringValue(sConfigID + ".cursor");
 		if (sCursor != null && sCursor.length() > 0) {
 			if (sCursor.equalsIgnoreCase("hand")) {
-				label.addListener(SWT.MouseEnter,
-						skin.getHandCursorListener(label.getDisplay()));
-				label.addListener(SWT.MouseExit,
-						skin.getHandCursorListener(label.getDisplay()));
+				canvas.addListener(SWT.MouseEnter,
+						skin.getHandCursorListener(canvas.getDisplay()));
+				canvas.addListener(SWT.MouseExit,
+						skin.getHandCursorListener(canvas.getDisplay()));
 			}
 		}
 
 		//		SWTBGImagePainter painter = (SWTBGImagePainter) parent.getData("BGPainter");
 		//		if (painter != null) {
-		//			label.addListener(SWT.Paint, painter);
+		//			canvas.addListener(SWT.Paint, painter);
 		//		}
-		label.addDisposeListener(new DisposeListener() {
+		canvas.addDisposeListener(new DisposeListener() {
 			public void widgetDisposed(DisposeEvent e) {
-				String oldImageID = (String) label.getData("ImageID");
-				if (oldImageID != null && label.getData("image") != null) {
+				String oldImageID = (String) canvas.getData("ImageID");
+				if (oldImageID != null && canvas.getData("image") != null) {
 					ImageLoader imageLoader = skin.getImageLoader(properties);
 					imageLoader.releaseImage(oldImageID);
 				}
 			}
 		});
 
-		return label;
+		// needed to set paint listener and canvas size
+		reallySetImage();
+
+		return canvas;
 	}
 	
 	public void setVisible(boolean visible) {
@@ -232,36 +231,32 @@ public class SWTSkinObjectImage
 
 		if (visible) {
 			reallySetImage();
-		} else {
-			if (!customImage) {
-				label.setImage(null);
-			}
 		}
 	}
 
-	//protected void setLabelImage(String sConfigID, AECallback<Image> callback) {
-	protected void setLabelImage(String sImageID, AECallback callback) {
-		setLabelImage(sConfigID, sImageID, callback);
+	//protected void setCanvasImage(String sConfigID, AECallback<Image> callback) {
+	protected void setCanvasImage(String sImageID, AECallback callback) {
+		setCanvasImage(sConfigID, sImageID, callback);
 	}
 
-	//private void setLabelImage(final String sConfigID, final String sImageID, AECallback<Image> callback) {
-	private void setLabelImage(final String sConfigID, final String sImageID,
+	//private void setCanvasImage(final String sConfigID, final String sImageID, AECallback<Image> callback) {
+	private void setCanvasImage(final String sConfigID, final String sImageID,
 			AECallback callback) {
 		Utils.execSWTThread(new AERunnableWithCallback(callback) {
 
 			public Object runSupport() {
-				if (label == null || label.isDisposed()) {
+				if (canvas == null || canvas.isDisposed()) {
 					return null;
 				}
 
-				String oldImageID = (String) label.getData("ImageID");
+				String oldImageID = (String) canvas.getData("ImageID");
 				if (sImageID != null && sImageID.equals(oldImageID)) {
 					return null;
 				}
 
 				ImageLoader imageLoader = skin.getImageLoader(properties);
 
-				if (oldImageID != null && label.getData("image") != null) {
+				if (oldImageID != null && canvas.getData("image") != null) {
 					imageLoader.releaseImage(oldImageID);
 				}
 
@@ -273,14 +268,14 @@ public class SWTSkinObjectImage
 				if (images.length == 3) {
 					Image imageLeft = images[0];
 					if (ImageLoader.isRealImage(imageLeft)) {
-						label.setData("image-left", imageLeft);
+						canvas.setData("image-left", imageLeft);
 					}
 
 					image = images[1];
 
 					Image imageRight = images[2];
 					if (ImageLoader.isRealImage(imageRight)) {
-						label.setData("image-right", imageRight);
+						canvas.setData("image-right", imageRight);
 					}
 				} else if (images.length > 0) {
 					image = images[0];
@@ -312,55 +307,37 @@ public class SWTSkinObjectImage
 				} else {
 					drawMode = DRAW_NORMAL;
 				}
-				label.setData("drawmode", drawMode);
-
-				if (drawMode != DRAW_NORMAL || ALWAYS_USE_PAINT) {
-					noSetLabelImage = true;
-					Rectangle imgBounds = image.getBounds();
-					if (drawMode != DRAW_CENTER && drawMode != DRAW_HCENTER
-							&& drawMode != DRAW_STRETCH) {
-						label.setSize(imgBounds.width, imgBounds.height);
-					}
-					//label.setData("image", image);
-
-					if (drawMode == DRAW_TILE || drawMode == DRAW_NORMAL) {
-						// XXX Huh? A tile of one? :)
-						FormData fd = (FormData) label.getLayoutData();
-						if (fd == null) {
-							fd = new FormData(imgBounds.width, imgBounds.height);
-						} else {
-							fd.width = imgBounds.width;
-							fd.height = imgBounds.height;
-						}
-						label.setLayoutData(fd);
-						Utils.relayout(label);
-					}
-					
-					// remove in case already added
-					label.removePaintListener(paintListener);
-
-					label.addPaintListener(paintListener);
+				canvas.setData("drawmode", drawMode);
 
-					label.setImage(null);
-				} else if (sDrawMode.equals(("scale"))) {
-					noSetLabelImage = true;
-					Rectangle imgBounds = image.getBounds();
-					label.setSize(imgBounds.width, imgBounds.height);
-					label.setData("image", image);
+				Rectangle imgBounds = image.getBounds();
+				if (drawMode != DRAW_CENTER && drawMode != DRAW_HCENTER
+						&& drawMode != DRAW_STRETCH) {
+					canvas.setSize(imgBounds.width, imgBounds.height);
+				}
+				//canvas.setData("image", image);
 
-				} else {
-					Image oldImage = label.getImage();
-					label.setImage(image);
-					if (oldImage == null || image == null
-							|| !oldImage.getBounds().equals(image.getBounds())) {
-						Utils.relayout(label);
+				if (drawMode == DRAW_TILE || drawMode == DRAW_NORMAL) {
+					// XXX Huh? A tile of one? :)
+					FormData fd = (FormData) canvas.getLayoutData();
+					if (fd == null) {
+						fd = new FormData(imgBounds.width, imgBounds.height);
+					} else {
+						fd.width = imgBounds.width;
+						fd.height = imgBounds.height;
 					}
+					canvas.setLayoutData(fd);
+					Utils.relayout(canvas);
 				}
-				label.setData("ImageID", sImageID);
+				
+				// remove in case already added
+				canvas.removePaintListener(paintListener);
 
-				label.redraw();
+				canvas.addPaintListener(paintListener);
+				canvas.setData("ImageID", sImageID);
 
-				SWTSkinUtils.addMouseImageChangeListeners(label);
+				canvas.redraw();
+
+				SWTSkinUtils.addMouseImageChangeListeners(canvas);
 				imageLoader.releaseImage(sImageID);
 				return null;
 			}
@@ -401,7 +378,7 @@ public class SWTSkinObjectImage
 	}
 
 	protected void reallySetImage() {
-		if (label.getImage() != null || currentImageID == null || customImage) {
+		if (currentImageID == null || customImage) {
 			return;
 		}
 
@@ -411,7 +388,7 @@ public class SWTSkinObjectImage
 			currentImageID = sConfigID + ".image";
 			imageExists = true;
 		}
-		if (!imageExists) {
+		if (!imageExists && suffixes != null) {
 			for (int i = suffixes.length - 1; i >= 0; i--) {
 				String suffixToRemove = suffixes[i];
 				if (suffixToRemove != null) {
@@ -426,26 +403,18 @@ public class SWTSkinObjectImage
 		}
 
 		if (imageExists) {
-			setLabelImage(currentImageID, null);
+			setCanvasImage(currentImageID, null);
 		}
 	}
 
-	public Image getImage() {
-		return label.getImage();
-	}
-
 	public void setImage(Image image) {
 		customImage = true;
 		customImageID = null;
-		label.setData("image", image);
-		label.setData("image-left", null);
-		label.setData("image-right", null);
-		if (!noSetLabelImage) {
-			label.setImage(image);
-		} else {
-			label.redraw();
-		}
-		Utils.relayout(label);
+		canvas.setData("image", image);
+		canvas.setData("image-left", null);
+		canvas.setData("image-right", null);
+		canvas.redraw();
+		Utils.relayout(canvas);
 	}
 
 	protected void setImageByID(String sConfigID, AECallback callback) {
@@ -463,9 +432,9 @@ public class SWTSkinObjectImage
 		ImageLoader imageLoader = skin.getImageLoader(properties);
 		Image image = imageLoader.getImage(sImageID);
 		if (ImageLoader.isRealImage(image)) {
-			setLabelImage(sConfigID, sImageID, callback);
+			setCanvasImage(sConfigID, sImageID, callback);
 		} else {
-			setLabelImage(sConfigID, sConfigID, callback);
+			setCanvasImage(sConfigID, sConfigID, callback);
 		}
 		imageLoader.releaseImage(sImageID);
 		return;
@@ -484,7 +453,7 @@ public class SWTSkinObjectImage
 				final ImageLoader imageLoader = skin.getImageLoader(properties);
 				imageLoader.getUrlImage(url, new ImageDownloaderListener() {
 					public void imageDownloaded(Image image, boolean returnedImmediately) {
-						setLabelImage(url, null);
+						setCanvasImage(url, null);
 						imageLoader.releaseImage(url);
 					}
 				});
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectSash.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectSash.java
index da2f785..1023456 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectSash.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectSash.java
@@ -292,7 +292,7 @@ public class SWTSkinObjectSash
 
 			public void handleEvent(Event e) {
 				if (e.type == SWT.MouseUp) {
-					if (e.button == 2 || (e.button == 3 && (e.stateMask & SWT.MOD1) > 0)) {
+					if (e.button == 3 || (e.button == 1 && (e.stateMask & SWT.MOD1) > 0)) {
 						String sPos = properties.getStringValue(sConfigID + ".startpos");
 						if (sPos == null) {
 							return;
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinTabSet.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinTabSet.java
index 9b545eb..cf9f870 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinTabSet.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinTabSet.java
@@ -170,27 +170,6 @@ public class SWTSkinTabSet
 			parent.getControl().setFocus();
 		}
 
-		if (org.gudy.azureus2.core3.util.Constants.isOSX) {
-			boolean bHasSkinBrowser = false;
-			SWTSkinObject[] activeWidgets = activeTab.getActiveWidgets(true);
-			for (int i = 0; i < activeWidgets.length; i++) {
-				SWTSkinObject skinObject = activeWidgets[i];
-				if (hasSkinBrowser(skinObject)) {
-					bHasSkinBrowser = true;
-					break;
-				}
-			}
-
-			if (bHasSkinBrowser) {
-				Shell shell = activeTab.getControl().getShell();
-				Point size = shell.getSize();
-				size.x -= 1;
-				shell.setSize(size);
-				size.x += 1;
-				shell.setSize(size);
-			}
-		}
-
 		triggerChangeListener(sOldID, sNewID);
 	}
 
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinUtils.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinUtils.java
index 8975e5a..f98bf79 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinUtils.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinUtils.java
@@ -5,17 +5,14 @@ package com.aelitis.azureus.ui.swt.skin;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.AERunnableBoolean;
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.components.shell.LightBoxShell;
-
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 
 /**
  * @author TuxPaper
diff --git a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionListWindow.java b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionListWindow.java
index 3d62806..08747f2 100644
--- a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionListWindow.java
+++ b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionListWindow.java
@@ -24,22 +24,16 @@ import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AEThread2;
-import org.gudy.azureus2.ui.swt.ImageRepository;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 
-import com.aelitis.azureus.core.metasearch.Engine;
 import com.aelitis.azureus.core.subs.Subscription;
 import com.aelitis.azureus.core.subs.SubscriptionAssociationLookup;
 import com.aelitis.azureus.core.subs.SubscriptionException;
-import com.aelitis.azureus.core.subs.SubscriptionHistory;
-import com.aelitis.azureus.core.subs.SubscriptionListener;
 import com.aelitis.azureus.core.subs.SubscriptionLookupListener;
 import com.aelitis.azureus.core.subs.SubscriptionManager;
 import com.aelitis.azureus.core.subs.SubscriptionManagerFactory;
 import com.aelitis.azureus.core.subs.SubscriptionPopularityListener;
-import com.aelitis.azureus.core.vuzefile.VuzeFile;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 import com.aelitis.azureus.ui.swt.widgets.AnimatedImage;
 
 public class SubscriptionListWindow implements SubscriptionLookupListener {
@@ -81,18 +75,9 @@ public class SubscriptionListWindow implements SubscriptionLookupListener {
 		this.download 		= download;
 		this.useCachedSubs	= useCachedSubs;
 		
-		UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
-		if(functionsSWT != null) {
-			Shell mainShell = functionsSWT.getMainShell();
-			shell = new Shell(mainShell,SWT.TITLE);
-			shell.setSize(400,300);
-			Utils.centerWindowRelativeTo(shell, mainShell);
-			
-		} else {
-			shell = new Shell(SWT.TITLE);
-			shell.setSize(400,300);
-			Utils.centreWindow(shell);
-		}
+		shell = ShellFactory.createMainShell(SWT.TITLE);
+		shell.setSize(400,300);
+		Utils.centreWindow(shell);
 		
 		display = shell.getDisplay();
 		shell.setText(MessageText.getString("subscriptions.listwindow.title"));
diff --git a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionManagerUI.java b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionManagerUI.java
index 38135de..0fc43aa 100644
--- a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionManagerUI.java
+++ b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionManagerUI.java
@@ -30,6 +30,8 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.Browser;
 import org.eclipse.swt.browser.ProgressEvent;
 import org.eclipse.swt.browser.ProgressListener;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
@@ -47,6 +49,7 @@ import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.plugins.ui.*;
 import org.gudy.azureus2.plugins.ui.config.BooleanParameter;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
+import org.gudy.azureus2.plugins.ui.config.HyperlinkParameter;
 import org.gudy.azureus2.plugins.ui.config.IntParameter;
 import org.gudy.azureus2.plugins.ui.config.Parameter;
 import org.gudy.azureus2.plugins.ui.config.ParameterListener;
@@ -63,7 +66,6 @@ import org.gudy.azureus2.plugins.utils.Utilities;
 import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.CategoryAdderWindow;
-import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.PropertiesWindow;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
@@ -76,7 +78,6 @@ import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
 
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
-import com.aelitis.azureus.core.devices.TranscodeFile;
 import com.aelitis.azureus.core.messenger.ClientMessageContext;
 import com.aelitis.azureus.core.metasearch.Engine;
 import com.aelitis.azureus.core.metasearch.impl.web.WebEngine;
@@ -84,6 +85,7 @@ import com.aelitis.azureus.core.subs.*;
 import com.aelitis.azureus.core.vuzefile.VuzeFile;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
 import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
@@ -109,6 +111,10 @@ SubscriptionManagerUI
 	public static final Object	SUB_IVIEW_KEY 		= new Object();
 	public static final Object	SUB_EDIT_MODE_KEY 	= new Object();
 	
+	public static final String ALERT_IMAGE_ID	= "image.sidebar.vitality.alert";
+	public static final String AUTH_IMAGE_ID	= "image.sidebar.vitality.auth";
+	
+
 	private static final String EDIT_MODE_MARKER	= "&editMode=1";
 	
 	private Graphic	icon_rss_big;
@@ -532,6 +538,37 @@ SubscriptionManagerUI
 			});
 
 		
+			// rss
+		
+		final BooleanParameter rss_enable = 
+			configModel.addBooleanParameter2( 
+				"subscriptions.rss.enable", "subscriptions.rss.enable",
+				subs_man.isRSSPublishEnabled());
+		
+		rss_enable.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param) 
+				{
+					subs_man.setRSSPublishEnabled( rss_enable.getValue());
+				}
+			});
+				
+		HyperlinkParameter rss_view = 
+			configModel.addHyperlinkParameter2(
+				"device.rss.view", subs_man.getRSSLink());
+		
+		rss_enable.addEnabledOnSelection( rss_view );
+		
+		configModel.createGroup(
+			"device.rss.group",
+			new Parameter[]
+			{
+					rss_enable, rss_view,
+			});
+		
 		SideBar sideBar = (SideBar)SkinViewManager.getByClass(SideBar.class);
 		
 		if ( sideBar != null ){
@@ -698,7 +735,7 @@ SubscriptionManagerUI
 				public void tableColumnCreated(TableColumn result) {
 					result.setAlignment(TableColumn.ALIGN_CENTER);
 					result.setPosition(TableColumn.POSITION_LAST);
-					result.setWidth(75);
+					result.setWidth(72);
 					result.setRefreshInterval(TableColumn.INTERVAL_INVALID_ONLY);
 					result.setType(TableColumn.TYPE_GRAPHIC);
 				
@@ -840,7 +877,7 @@ SubscriptionManagerUI
 		
 		if (mainSBEntry != null) {
 			
-			SideBarVitalityImage addSub = mainSBEntry.addVitalityImage("image.sidebar.subs.add");
+			SideBarVitalityImage addSub 	= mainSBEntry.addVitalityImage("image.sidebar.subs.add");
 			
 			addSub.setToolTip("Add Subscription");
 			
@@ -850,6 +887,10 @@ SubscriptionManagerUI
 				}
 			});
 			
+			final SideBarVitalityImage warnSub 	= mainSBEntry.addVitalityImage( ALERT_IMAGE_ID );
+			
+			warnSub.setVisible( false );
+			
 			mainSBEntry.setImageLeftID("image.sidebar.subscriptions");
 
 			mainSBEntry.setTitleInfo(
@@ -867,17 +908,38 @@ SubscriptionManagerUI
 
 							boolean expanded = mainSBEntry.getTreeItem().getExpanded();
 
-							if ( !expanded ){
+							if ( expanded ){
+								
+								warnSub.setVisible( false );
+								
+							}else{
 								
-								int	total = 0;
+								int		total 	= 0;
+								boolean	warn 	= false;
 								
 								Subscription[] subs = subs_man.getSubscriptions();
 								
 								for ( Subscription s: subs ){
 									
-									total += s.getHistory().getNumUnread();
+									SubscriptionHistory history = s.getHistory();
+
+									total += history.getNumUnread();
+									
+									String	last_error = history.getLastError();
+
+									if ( last_error != null ){
+										
+										boolean	auth_fail = history.isAuthFail();
+																		
+										if ( history.getConsecFails() >= 3 || auth_fail ){
+										
+											warn = true;
+										}
+									}
 								}
 								
+								warnSub.setVisible( warn );
+								
 								if ( total > 0 ){
 								
 									return( String.valueOf( total ));
@@ -985,13 +1047,13 @@ SubscriptionManagerUI
 			public void selected(MenuItem menu, Object target) {
 				if (target instanceof SideBarEntry) {
 					SideBarEntry info = (SideBarEntry) target;
-					Subscription subs = (Subscription) info.getDatasource();
+					final Subscription subs = (Subscription) info.getDatasource();
 					try{
 						Engine engine = subs.getEngine();
 						
 						if ( engine instanceof WebEngine ){
 							
-							WebEngine we = (WebEngine)engine;
+							final WebEngine we = (WebEngine)engine;
 							
 							UISWTInputReceiver entry = (UISWTInputReceiver)swt_ui.getInputReceiver();
 							
@@ -1007,20 +1069,28 @@ SubscriptionManagerUI
 							entry.maintainWhitespace(false);
 							entry.allowEmptyInput( false );
 							entry.setTitle("general.enter.cookies");
-							entry.prompt();
-							if (!entry.hasSubmittedInput()){
-								
-								return;
-							}
-							
-							String input = entry.getSubmittedInput().trim();
-							
-							if ( input.length() > 0 ){
-							
-								we.setCookies( input );
-								
-								subs.getManager().getScheduler().downloadAsync(subs, true);
-							}
+							entry.prompt(new UIInputReceiverListener() {
+								public void UIInputReceiverClosed(UIInputReceiver entry) {
+									if (!entry.hasSubmittedInput()){
+										
+										return;
+									}
+
+									try {
+  									String input = entry.getSubmittedInput().trim();
+  									
+  									if ( input.length() > 0 ){
+  										
+  										we.setCookies( input );
+  										
+  										subs.getManager().getScheduler().downloadAsync(subs, true);
+  									}
+									}catch( Throwable e ){
+										
+										Debug.printStackTrace(e);
+									}
+								}
+							});
 						}
 					}catch( Throwable e ){
 						
@@ -1116,31 +1186,37 @@ SubscriptionManagerUI
 			public void selected(MenuItem menu, Object target) {
 				if (target instanceof SideBarEntry) {
 					SideBarEntry info = (SideBarEntry) target;
-					Subscription subs = (Subscription) info.getDatasource();
+					final Subscription subs = (Subscription) info.getDatasource();
 					
 					UISWTInputReceiver entry = (UISWTInputReceiver)swt_ui.getInputReceiver();
 					entry.setPreenteredText(subs.getName(), false );
 					entry.maintainWhitespace(false);
 					entry.allowEmptyInput( false );
-					entry.setTitle("MyTorrentsView.menu.rename");
-					entry.prompt();
-					if (!entry.hasSubmittedInput()){
-						
-						return;
-					}
-					
-					String input = entry.getSubmittedInput().trim();
-					
-					if ( input.length() > 0 ){
-						
-						try{
-							subs.setName( input );
+					entry.setLocalisedTitle(MessageText.getString("label.rename",
+							new String[] {
+								subs.getName()
+							}));
+					entry.prompt(new UIInputReceiverListener() {
+						public void UIInputReceiverClosed(UIInputReceiver entry) {
+							if (!entry.hasSubmittedInput()){
+								
+								return;
+							}
 							
-						}catch( Throwable e ){
+							String input = entry.getSubmittedInput().trim();
 							
-							Debug.printStackTrace(e);
+							if ( input.length() > 0 ){
+								
+								try{
+									subs.setName( input );
+									
+								}catch( Throwable e ){
+									
+									Debug.printStackTrace(e);
+								}
+							}
 						}
-					}
+					});
 				}
 			}
 		};
@@ -1296,7 +1372,7 @@ SubscriptionManagerUI
 	{
 		if ( subs.isSubscribed()){
 			
-			addSubscription( side_bar, subs, true );
+			addSubscription( side_bar, subs, false );
 			
 		}else{
 			
@@ -1326,6 +1402,19 @@ SubscriptionManagerUI
 				final sideBarItem new_si = new sideBarItem();
 				
 				subs.setUserData( SUB_IVIEW_KEY, new_si );
+
+				// GetEngine used to be near menu item created, but was moved here
+				// since it takes time on first start and we don't want it stalling
+				// the UI Thread
+				Engine e = null;
+				try{
+					e = subs.getEngine();
+					
+				}catch( Throwable ex ){
+					
+					Debug.printStackTrace(ex);
+				}
+				final Engine engine = e;
 				
 				Utils.execSWTThread(
 					new Runnable()
@@ -1386,11 +1475,9 @@ SubscriptionManagerUI
 								menuItem.addListener(resetResultsListener);
 
 								try{
-									Engine e = subs.getEngine();
-									
-									if ( e instanceof WebEngine ){
+									if ( engine instanceof WebEngine ){
 										
-										if (((WebEngine)e).isNeedsAuth()){
+										if (((WebEngine)engine).isNeedsAuth()){
 											
 											menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.resetauth");
 											menuItem.addListener(resetAuthListener);
@@ -1621,11 +1708,10 @@ SubscriptionManagerUI
 	
 	protected static void
 	removeWithConfirm(
-		Subscription	subs )
+		final Subscription	subs )
 	{
 		MessageBoxShell mb = 
 			new MessageBoxShell(
-				Utils.findAnyShell(),
 				MessageText.getString("message.confirm.delete.title"),
 				MessageText.getString("message.confirm.delete.text",
 						new String[] {
@@ -1637,10 +1723,13 @@ SubscriptionManagerUI
 				},
 				1 );
 		
-		int result = mb.open();
-		if (result == 0) {
-			subs.remove();
-		}
+		mb.open(new UserPrompterResultListener() {
+			public void prompterClosed(int result) {
+				if (result == 0) {
+					subs.remove();
+				}
+			}
+		});
 	}
 	
 	protected void
@@ -1859,15 +1948,6 @@ SubscriptionManagerUI
 		}
 		
 		public void delete() {
-			// Fix/Hack for SWT Browser disposal bug + memory leak
-			if(mainBrowser != null && ! mainBrowser.isDisposed()) {
-				mainBrowser.setUrl("about:blank");
-				mainBrowser.setVisible(false);
-			}
-			if(detailsBrowser != null && ! detailsBrowser.isDisposed()) {
-				detailsBrowser.setUrl("about:blank");
-				detailsBrowser.setVisible(false);
-			}
 			super.delete();
 		}
 		
@@ -2019,6 +2099,13 @@ SubscriptionManagerUI
 		{
 			try{
 				mainBrowser = new Browser(composite,Utils.getInitialBrowserStyle(SWT.NONE));
+				mainBrowser.addDisposeListener(new DisposeListener() {
+					public void widgetDisposed(DisposeEvent e) {
+						((Browser)e.widget).setUrl("about:blank");
+						((Browser)e.widget).setVisible(false);
+						while (!e.display.isDisposed() && e.display.readAndDispatch());
+					}
+				});
 				BrowserContext context = 
 					new BrowserContext("browser-window"	+ Math.random(), mainBrowser, null, true);
 				
@@ -2067,6 +2154,13 @@ SubscriptionManagerUI
 				mainBrowser.setLayoutData(data);
 				
 				detailsBrowser = new Browser(composite,Utils.getInitialBrowserStyle(SWT.NONE));
+				detailsBrowser.addDisposeListener(new DisposeListener() {
+					public void widgetDisposed(DisposeEvent e) {
+						((Browser)e.widget).setUrl("about:blank");
+						((Browser)e.widget).setVisible(false);
+						while (!e.display.isDisposed() && e.display.readAndDispatch());
+					}
+				});
 				BrowserContext detailsContext = 
 					new BrowserContext("browser-window"	+ Math.random(), detailsBrowser, null, false);
 				detailsContext.addListener(new BrowserContext.loadingListener(){
@@ -2121,7 +2215,6 @@ SubscriptionManagerUI
 				detailsContext.addMessageListener(new VuzeListener());
 				detailsContext.addMessageListener(new DisplayListener(detailsBrowser));
 				detailsContext.addMessageListener(new ConfigListener(detailsBrowser));
-				detailsContext.addMessageListener(new LightBoxBrowserRequestListener());
 				url = "about:blank";
 				detailsBrowser.setUrl(url);
 				detailsBrowser.setData("StartURL", url);
@@ -2187,9 +2280,6 @@ SubscriptionManagerUI
 		{
 			if ( mainBrowser != null ){
 			
-				//OSX bug : browsers don't really get disposed
-				mainBrowser.setUrl("about:blank");
-				
 				mainBrowser.dispose();
 				
 				mainBrowser = null;
@@ -2197,9 +2287,6 @@ SubscriptionManagerUI
 			
 			if ( detailsBrowser != null ){
 				
-				//OSX bug : browsers don't really get disposed
-				detailsBrowser.setUrl("about:blank");
-			
 				detailsBrowser.dispose();
 
 				detailsBrowser = null;
@@ -2429,9 +2516,6 @@ SubscriptionManagerUI
 	public static class
 	sideBarItem
 	{
-		public static final String ALERT_IMAGE_ID	= "image.sidebar.vitality.alert";
-		public static final String AUTH_IMAGE_ID	= "image.sidebar.vitality.auth";
-		
 		private subscriptionView	view;
 		private SideBarEntrySWT		sb_entry;
 		private TreeItem			tree_item;
diff --git a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionSelectedContent.java b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionSelectedContent.java
index 161e99b..716166e 100644
--- a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionSelectedContent.java
+++ b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionSelectedContent.java
@@ -97,29 +97,35 @@ SubscriptionSelectedContent
 				
 					VuzeFile vf = subs.getVuzeFile();
 				
-					File f1 = AETemporaryFileHandler.createTempFile();
+						// if not corrupt....
 					
-					File f = new File( f1.getParent(), "Update Vuze to access this share_" + f1.getName());
-					
-					f1.delete();
-					
-					try{
-					
-						vf.write( f );
-					
-						TOTorrentCreator cr = TOTorrentFactory.createFromFileOrDirWithComputedPieceLength( f, new URL( "dht://" ));
+					if ( vf != null ){
+						
+						File f1 = AETemporaryFileHandler.createTempFile();
 						
-						TOTorrent temp = cr.create();
+						File f = new File( f1.getParent(), "Update Vuze to access this share_" + f1.getName());
 						
-						Map	vuze_map 	= vf.exportToMap();
-						Map	torrent_map = temp.serialiseToMap();
+						f1.delete();
 						
-						torrent_map.putAll( vuze_map );
+						try{
 						
-						torrent = TOTorrentFactory.deserialiseFromMap( torrent_map );
-					}finally{
+							vf.write( f );
 						
-						f.delete();
+							TOTorrentCreator cr = TOTorrentFactory.createFromFileOrDirWithComputedPieceLength( f, new URL( "dht://" ));
+							
+							TOTorrent temp = cr.create();
+							
+							Map	vuze_map 	= vf.exportToMap();
+							Map	torrent_map = temp.serialiseToMap();
+							
+							torrent_map.putAll( vuze_map );
+							
+							torrent = TOTorrentFactory.deserialiseFromMap( torrent_map );
+							
+						}finally{
+							
+							f.delete();
+						}
 					}
 				}catch( Throwable e ){
 					
diff --git a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionWizard.java b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionWizard.java
index 595c0b6..cedaa64 100644
--- a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionWizard.java
+++ b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionWizard.java
@@ -14,14 +14,13 @@ import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.CustomTableTooltipHandler;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.subs.*;
 import com.aelitis.azureus.core.subs.SubscriptionUtils.SubscriptionDownloadDetails;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 import com.aelitis.azureus.ui.swt.shells.main.MainWindow;
 import com.aelitis.azureus.ui.swt.utils.ColorCache;
@@ -126,17 +125,9 @@ public class SubscriptionWizard {
 		});
 		
 		
-		UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
-		if(functionsSWT != null) {
-			Shell mainShell = functionsSWT.getMainShell();
-			shell = new Shell(mainShell,SWT.TITLE | SWT.CLOSE | SWT.ICON | SWT.RESIZE);
-			shell.setSize(650,400);
-			Utils.centerWindowRelativeTo(shell, mainShell);
-		} else {
-			shell = new Shell(SWT.TITLE | SWT.CLOSE | SWT.RESIZE);
-			shell.setSize(650,400);
-			Utils.centreWindow(shell);
-		}
+		shell = ShellFactory.createMainShell(SWT.TITLE | SWT.CLOSE | SWT.RESIZE);
+		shell.setSize(650,400);
+		Utils.centreWindow(shell);
 		
 		shell.setMinimumSize(550,400);
 		
diff --git a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionsView.java b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionsView.java
index fdefa6a..214a44f 100644
--- a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionsView.java
+++ b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionsView.java
@@ -23,6 +23,7 @@ import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
 import com.aelitis.azureus.core.subs.Subscription;
 import com.aelitis.azureus.core.subs.SubscriptionManagerFactory;
 import com.aelitis.azureus.core.subs.SubscriptionManagerListener;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 import com.aelitis.azureus.ui.common.table.*;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
@@ -119,27 +120,61 @@ public class SubscriptionsView
 
 	private void removeSelected() {
 		TableRowCore[] rows = view.getSelectedRows();
-		for(int i = 0 ; i < rows.length ; i++) {
-			Subscription subs = (Subscription) rows[i].getDataSource();
-			MessageBoxShell mb = 
-				new MessageBoxShell(
-					Utils.findAnyShell(),
-					MessageText.getString("message.confirm.delete.title"),
-					MessageText.getString("message.confirm.delete.text",
-							new String[] {
-								subs.getName()
-							}), 
-					new String[] {
-						MessageText.getString("Button.yes"),
-						MessageText.getString("Button.no")
-					},
-					1 );
-			
-			int result = mb.open();
-			if (result == 0) {
-				subs.remove();
+		Subscription[] subs = new Subscription[rows.length];
+		int i = 0;
+		for (Subscription subscription : subs) {
+			subs[i] = (Subscription) rows[i++].getDataSource();
+		}
+		removeSubs(subs, 0);
+	}
+	
+	private void removeSubs(final Subscription[] toRemove, final int startIndex) {
+		if (toRemove[startIndex] == null) {
+			int nextIndex = startIndex + 1;
+			if (nextIndex < toRemove.length) {
+				removeSubs(toRemove, nextIndex);
 			}
+			return;
+		}
+
+		MessageBoxShell mb = new MessageBoxShell(
+				MessageText.getString("message.confirm.delete.title"),
+				MessageText.getString("message.confirm.delete.text", new String[] {
+					toRemove[startIndex].getName()
+				}));
+
+		if (startIndex == toRemove.length - 1) {
+			mb.setButtons(0, new String[] {
+				MessageText.getString("Button.yes"),
+				MessageText.getString("Button.no"),
+			}, new Integer[] { 0, 1 });
+		} else {
+			mb.setButtons(1, new String[] {
+				MessageText.getString("Button.removeAll"),
+				MessageText.getString("Button.yes"),
+				MessageText.getString("Button.no"),
+			}, new Integer[] { 2, 0, 1 });
 		}
+
+		mb.open(new UserPrompterResultListener() {
+			public void prompterClosed(int result) {
+				if (result == 0) {
+					toRemove[startIndex].remove();
+				} else if (result == 2) {
+					for (int i = startIndex; i < toRemove.length; i++) {
+						if (toRemove[i] != null) {
+							toRemove[i].remove();
+						}
+					}
+					return;
+				}
+
+				int nextIndex = startIndex + 1;
+				if (nextIndex < toRemove.length) {
+					removeSubs(toRemove, nextIndex);
+				}
+			}
+		});
 	}
 	
 	public void updateUI() {
diff --git a/com/aelitis/azureus/ui/swt/test/BrowserFlicker.java b/com/aelitis/azureus/ui/swt/test/BrowserFlicker.java
deleted file mode 100644
index 70fdbcb..0000000
--- a/com/aelitis/azureus/ui/swt/test/BrowserFlicker.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package com.aelitis.azureus.ui.swt.test;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.widgets.*;
-import org.gudy.azureus2.ui.swt.Utils;
-
-/**
- * Eclipse Bug 164512:
- * seizure inducing flicker on resize in Browser w/parent having paint listener
- * https://bugs.eclipse.org/bugs/show_bug.cgi?id=164512
- * 
- * @author TuxPaper
- * @created Nov 13, 2006
- *
- */
-public class BrowserFlicker
-{
-	final static int INDENT = 10;
-
-	public static void main(String[] args) {
-		final Display display = new Display();
-		final Shell shell = new Shell(display, SWT.SHELL_TRIM);
-
-		FormData fd;
-
-		shell.setLayout(new FormLayout());
-
-		final Composite right = new Composite(shell, SWT.NONE);
-		right.setLayout(new FormLayout());
-
-		final Browser b = new Browser(right, Utils.getInitialBrowserStyle(SWT.NONE));
-		fd = new FormData();
-		fd.top = new FormAttachment(0, INDENT);
-		fd.left = new FormAttachment(0, INDENT);
-		fd.right = new FormAttachment(100, -INDENT);
-		fd.bottom = new FormAttachment(100, -INDENT);
-		b.setLayoutData(fd);
-		// black so we can see the flicker better
-		b.setText("<html><body BGCOLOR=black></body></html>");
-
-		fd = new FormData();
-		fd.top = new FormAttachment(0);
-		fd.left = new FormAttachment(50);
-		fd.bottom = new FormAttachment(100);
-		fd.right = new FormAttachment(100);
-		right.setLayoutData(fd);
-
-		shell.addListener(SWT.Resize, new Listener() {
-			public void handleEvent(Event event) {
-				// code here to resulting in a need to re-layout
-
-				right.getParent().layout();
-			}
-		});
-
-		Listener l = new Listener() {
-			public void handleEvent(Event event) {
-				Point size = ((Control) event.widget).getSize();
-				event.gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
-				event.gc.fillOval(0, 0, INDENT, INDENT);
-				event.gc.fillOval(size.x - INDENT, 0, INDENT, INDENT);
-				event.gc.fillOval(size.x - INDENT, size.y - INDENT, INDENT, INDENT);
-				event.gc.fillOval(0, size.y - INDENT, INDENT, INDENT);
-
-				// mimic other work
-				try {
-					Thread.sleep(10);
-				} catch (InterruptedException e) {
-					e.printStackTrace();
-				}
-			}
-
-		};
-
-		right.addListener(SWT.Paint, l);
-		shell.setSize(200, 200);
-		shell.open();
-
-		while (!shell.isDisposed()) {
-			if (display.readAndDispatch()) {
-				display.sleep();
-			}
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/test/ImageOverImage.java b/com/aelitis/azureus/ui/swt/test/ImageOverImage.java
deleted file mode 100644
index 53854fa..0000000
--- a/com/aelitis/azureus/ui/swt/test/ImageOverImage.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.aelitis.azureus.ui.swt.test;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseTrackListener;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-public class ImageOverImage
-{
-	public static void main(String[] args) {
-		FormData formData;
-
-		Display display = new Display();
-
-		Shell shell = new Shell(display, SWT.DIALOG_TRIM);
-
-		FormLayout layout = new FormLayout();
-		shell.setLayout(layout);
-
-		Image image1 = new Image(display, 100, 100);
-
-		GC gc = new GC(image1);
-		gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
-		gc.fillRectangle(0, 0, 100, 100);
-		gc.dispose();
-
-		final Image image2 = new Image(display, 50, 50);
-		gc = new GC(image2);
-		gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
-		gc.fillRectangle(0, 0, 50, 50);
-		gc.dispose();
-
-		final Image image3 = new Image(display, 50, 50);
-		gc = new GC(image2);
-		gc.setBackground(display.getSystemColor(SWT.COLOR_GREEN));
-		gc.fillRectangle(0, 0, 50, 50);
-		gc.dispose();
-
-		Composite c1 = new Composite(shell, SWT.BORDER);
-		formData = new FormData();
-		formData.top = new FormAttachment(0, 0);
-		formData.left = new FormAttachment(0, 0);
-		formData.right = new FormAttachment(100);
-		formData.bottom = new FormAttachment(100);
-		c1.setLayoutData(formData);
-		c1.setLayout(new FormLayout());
-
-		final Composite c2 = new Composite(c1, SWT.BORDER);
-		formData = new FormData();
-		formData.top = new FormAttachment(00, 10);
-		formData.left = new FormAttachment(00, 10);
-		formData.right = new FormAttachment(100, -10);
-		formData.bottom = new FormAttachment(100, -10);
-		c2.setLayoutData(formData);
-
-		c1.setBackgroundImage(image1);
-		c2.setBackgroundImage(image2);
-
-		c2.addMouseTrackListener(new MouseTrackListener() {
-
-			public void mouseHover(MouseEvent e) {
-				// TODO Auto-generated method stub
-
-			}
-
-			public void mouseExit(MouseEvent e) {
-				c2.setBackgroundImage(image2);
-			}
-
-			public void mouseEnter(MouseEvent e) {
-				c2.setBackgroundImage(image3);
-			}
-
-		});
-
-		shell.setSize(100, 100);
-		shell.open();
-
-		while (!display.isDisposed()) {
-			if (!display.readAndDispatch()) {
-				display.sleep();
-			}
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/test/TorrentThumbnail.java b/com/aelitis/azureus/ui/swt/test/TorrentThumbnail.java
deleted file mode 100644
index 2eb9739..0000000
--- a/com/aelitis/azureus/ui/swt/test/TorrentThumbnail.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package com.aelitis.azureus.ui.swt.test;
-
-import java.io.*;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.torrent.TOTorrentException;
-import org.gudy.azureus2.core3.util.TorrentUtils;
-
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-
-/**
- * @author TuxPaper
- * @created Sep 28, 2006
- *
- */
-public class TorrentThumbnail
-{
-	public static byte[] b;
-
-	public static TOTorrent torrent;
-
-	public static String sFileName;
-
-	public static void main(String[] args) {
-		final Display display = new Display();
-		final Shell shell = new Shell(display, SWT.DIALOG_TRIM);
-
-		shell.setLayout(new FillLayout());
-
-		final Label image = new Label(shell, SWT.NONE);
-
-		Button btnGetTorrent = new Button(shell, SWT.PUSH);
-		btnGetTorrent.addSelectionListener(new SelectionListener() {
-			public void widgetSelected(SelectionEvent e) {
-				FileDialog fd = new FileDialog(shell);
-				sFileName = fd.open();
-				try {
-					torrent = TorrentUtils.readFromFile(new File(sFileName), false);
-				} catch (TOTorrentException e1) {
-					// TODO Auto-generated catch block
-					e1.printStackTrace();
-				}
-
-				b = PlatformTorrentUtils.getContentThumbnail(torrent);
-			}
-
-			public void widgetDefaultSelected(SelectionEvent e) {
-			}
-		});
-		btnGetTorrent.setText("Get Torrent");
-
-		Button btnShowImage = new Button(shell, SWT.PUSH);
-		btnShowImage.addSelectionListener(new SelectionListener() {
-			public void widgetSelected(SelectionEvent e) {
-				if (b == null) {
-					System.out.println("null");
-					return;
-				}
-				ByteArrayInputStream bis = new ByteArrayInputStream(b);
-				Image img = new Image(display, bis);
-				image.setImage(img);
-				shell.layout(true, true);
-			}
-
-			public void widgetDefaultSelected(SelectionEvent e) {
-			}
-		});
-		btnShowImage.setText("Show Image");
-
-		Button btnGetFile = new Button(shell, SWT.PUSH);
-		btnGetFile.addSelectionListener(new SelectionListener() {
-			public void widgetSelected(SelectionEvent e) {
-				FileDialog fd = new FileDialog(shell);
-				String sTFileName = fd.open();
-				b = getFileContents(sTFileName);
-				PlatformTorrentUtils.setContentThumbnail(torrent, b);
-				System.out.println("yay");
-				try {
-					TorrentUtils.writeToFile(torrent, new File(sFileName));
-				} catch (TOTorrentException e1) {
-					// TODO Auto-generated catch block
-					e1.printStackTrace();
-				}
-			}
-
-			public void widgetDefaultSelected(SelectionEvent e) {
-			}
-		});
-		btnGetFile.setText("Add thumb to torrent");
-
-		shell.open();
-
-		while (!shell.isDisposed()) {
-			if (display.readAndDispatch()) {
-				display.sleep();
-			}
-		}
-	}
-
-	public static byte[] getFileContents(String sFile) {
-		File f = new File(sFile);
-
-		try {
-			FileInputStream fs = new FileInputStream(f);
-
-			byte b[] = new byte[(int) f.length()];
-
-			fs.read(b);
-
-			fs.close();
-
-			return b;
-
-		} catch (FileNotFoundException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-
-		return null;
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/tests/TestPlatformMessenger.java b/com/aelitis/azureus/ui/swt/tests/TestPlatformMessenger.java
deleted file mode 100644
index 13ef53d..0000000
--- a/com/aelitis/azureus/ui/swt/tests/TestPlatformMessenger.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * Created on Apr 23, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
- 
-package com.aelitis.azureus.ui.swt.tests;
-
-import java.util.*;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.SystemTime;
-
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.messenger.*;
-import com.aelitis.azureus.core.messenger.config.PlatformRatingMessenger;
-import com.aelitis.azureus.util.ConstantsV3;
-
-import org.gudy.azureus2.plugins.PluginException;
-import org.gudy.azureus2.plugins.PluginInterface;
-
-/**
- * @author TuxPaper
- * @created Apr 23, 2008
- *
- */
-public class TestPlatformMessenger
-{
-	public void initialize(PluginInterface pi) throws PluginException {
-
-		PlatformMessenger.init();
-		Map parameters = new HashMap();
-		parameters.put("section-type", "browse");
-		parameters.put("locale", Locale.getDefault().toString());
-		System.out.println(SystemTime.getCurrentTime() + ": queueMessage 0");
-		PlatformMessenger.queueMessage(new PlatformMessage("AZMSG", "config",
-				"get-browse-sections", parameters, 150),
-				new PlatformMessengerListener() {
-
-					public void replyReceived(PlatformMessage message, String replyType,
-							Map reply) {
-						System.out.println(SystemTime.getCurrentTime() + ": replyRecieved "
-								+ message + ";" + replyType + ";" + reply);
-					}
-
-					public void messageSent(PlatformMessage message) {
-						System.out.println(SystemTime.getCurrentTime() + ": messageSent"
-								+ message);
-					}
-
-				});
-
-		parameters = new HashMap();
-		parameters.put("section-type", "minibrowse");
-		parameters.put("locale", Locale.getDefault().toString());
-		System.out.println(SystemTime.getCurrentTime() + ": queueMessage 1");
-		PlatformMessenger.queueMessage(new PlatformMessage("AZMSG", "config",
-				"get-browse-sections", parameters, 550),
-				new PlatformMessengerListener() {
-
-					public void replyReceived(PlatformMessage message, String replyType,
-							Map reply) {
-						System.out.println(SystemTime.getCurrentTime() + ": replyRecieved "
-								+ message + ";" + replyType + ";" + reply);
-					}
-
-					public void messageSent(PlatformMessage message) {
-						System.out.println(SystemTime.getCurrentTime() + ": messageSent"
-								+ message);
-					}
-
-				});
-
-		System.out.println(SystemTime.getCurrentTime() + ": queueMessage gr");
-		PlatformRatingMessenger.getUserRating(1l,
-				new String[] { PlatformRatingMessenger.RATE_TYPE_CONTENT
-				}, new String[] { "11"
-				}, 500);
-
-		System.out.println(SystemTime.getCurrentTime() + ": queueMessage 3");
-		//PlatformRatingMessenger.setUserRating("11", 1, false, 500, null);
-	}
-
-	public static void dumpMap(Map map, String indent) {
-		for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
-			Object key = (Object) iterator.next();
-			Object value = map.get(key);
-			if (value instanceof Map) {
-				System.out.println(key + " - " + ((Map) value).size());
-				dumpMap((Map) value, indent + "  ");
-			}
-			System.out.println(indent + key + ": " + value);
-		}
-	}
-
-	public static void main(String[] args) {
-		Display display = new Display();
-		Shell shell = new Shell(display, SWT.DIALOG_TRIM);
-		shell.open();
-
-		int count = 0;
-		try {
-			AzureusCore core = AzureusCoreFactory.create();
-			TestPlatformMessenger test = new TestPlatformMessenger();
-			test.initialize(core.getPluginManager().getDefaultPluginInterface());
-
-			while (!shell.isDisposed()) {
-				if (!display.readAndDispatch()) {
-					display.sleep();
-				}
-			}
-
-		} catch (Throwable e) {
-
-			Debug.printStackTrace(e);
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/utils/ContentNetworkUIManagerWindow.java b/com/aelitis/azureus/ui/swt/utils/ContentNetworkUIManagerWindow.java
deleted file mode 100644
index ef5e9b6..0000000
--- a/com/aelitis/azureus/ui/swt/utils/ContentNetworkUIManagerWindow.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * Created on Jan 8, 2009
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.ui.swt.utils;
-
-import java.util.Arrays;
-import java.util.Comparator;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.ui.swt.Utils;
-
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.skin.*;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
-import com.aelitis.azureus.ui.swt.utils.ContentNetworkUI.ContentNetworkImageLoadedListener;
-import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog;
-import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog.SkinnedDialogClosedListener;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
-import com.aelitis.azureus.util.ContentNetworkUtils;
-
-/**
- * @author TuxPaper
- * @created Jan 8, 2009
- *
- */
-public class ContentNetworkUIManagerWindow
-{
-	public ContentNetworkUIManagerWindow() {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				open();
-			}
-		});
-	}
-
-	protected void open() {
-		final SkinnedDialog dlg = new SkinnedDialog("skin3_manageCN",
-				"manageCN.body");
-		SWTSkin skin = dlg.getSkin();
-
-		SWTSkinObjectButton soButton = (SWTSkinObjectButton) skin.getSkinObject("close");
-		if (soButton != null) {
-			soButton.addSelectionListener(new ButtonListenerAdapter() {
-				public void pressed(SWTSkinButtonUtility buttonUtility,
-						SWTSkinObject skinObject, int stateMask) {
-					dlg.close();
-				}
-			});
-		}
-
-		SWTSkinObjectContainer soListArea = (SWTSkinObjectContainer) skin.getSkinObject("list-area");
-		if (soListArea != null) {
-			Composite parent = (Composite) soListArea.getControl();
-			ContentNetwork[] networks = ContentNetworkManagerFactory.getSingleton().getContentNetworks();
-			Arrays.sort(networks, new Comparator() {
-				public int compare(Object o1, Object o2) {
-					String p1 = ""
-							+ ((ContentNetwork) o1).getProperty(ContentNetwork.PROPERTY_ORDER);
-					String p2 = ""
-							+ ((ContentNetwork) o2).getProperty(ContentNetwork.PROPERTY_ORDER);
-
-					return p1.compareTo(p2);
-				}
-			});
-			Button lastButton = null;
-			for (int i = 0; i < networks.length; i++) {
-				final ContentNetwork cn = networks[i];
-				Object prop = cn.getProperty(ContentNetwork.PROPERTY_REMOVEABLE);
-				boolean removable = (prop instanceof Boolean)
-						? ((Boolean) prop).booleanValue() : false;
-				final Button button = new Button(parent, SWT.CHECK);
-				button.setText(cn.getName());
-
-				prop = cn.getPersistentProperty(ContentNetwork.PP_SHOW_IN_MENU);
-				boolean show = (prop instanceof Boolean)
-						? ((Boolean) prop).booleanValue() : true;
-
-				button.setSelection(show || !removable);
-				button.setEnabled(removable);
-
-				FormData fd = new FormData();
-				if (lastButton != null) {
-					fd.top = new FormAttachment(lastButton, 3);
-				} else {
-					fd.top = new FormAttachment(0, 5);
-				}
-				fd.left = new FormAttachment(0, 5);
-				//fd.right = new FormAttachment(100, -5);
-				button.setLayoutData(fd);
-
-				ContentNetworkUI.loadImage(cn.getID(),
-						new ContentNetworkImageLoadedListener() {
-							public void contentNetworkImageLoaded(Long contentNetworkID,
-									final Image image, final boolean wasReturned) {
-								if (image != null && image.getBounds().height < 50) {
-									button.setImage(image);
-									if (!wasReturned) {
-										button.getShell().layout(new Control[] {
-											button
-										});
-									}
-								}
-							}
-						});
-
-				lastButton = button;
-
-				button.addSelectionListener(new SelectionListener() {
-					public void widgetSelected(SelectionEvent e) {
-						Button button = (Button) e.widget;
-						boolean show = button.getSelection();
-						cn.setPersistentProperty(ContentNetwork.PP_SHOW_IN_MENU,
-								new Boolean(show));
-						if (!show) {
-							cn.setPersistentProperty(ContentNetwork.PP_AUTH_PAGE_SHOWN,
-									Boolean.FALSE);
-							// turn off notification window
-							cn.setPersistentProperty(ContentNetwork.PP_ACTIVE, Boolean.FALSE);
-
-							SideBarEntrySWT entry = SideBar.getEntry(ContentNetworkUtils.getTarget(cn));
-							if (entry.isInTree()) {
-								entry.getSidebar().closeEntry(entry.getId());
-							}
-							cn.setStartupNetwork(false);
-						} else {
-							// Uncomment to bring up sidebar entry on checking option
-							//String target = ContentNetworkUtils.getTarget(cn);
-							//SideBarEntrySWT entry = SideBar.getEntry(target);
-							//if (!entry.isInTree()) {
-							//	entry.getSidebar().showEntryByTabID(target);
-							//}
-						}
-					}
-
-					public void widgetDefaultSelected(SelectionEvent e) {
-					}
-				});
-				
-				String url = ContentNetworkUtils.getUrl(cn, ContentNetwork.SERVICE_ABOUT);
-				if (url != null) {
-					Link lblLearnMore = new Link(parent, SWT.NONE);
-					lblLearnMore.setText("<A HREF=\"" + url + "\">"
-							+ MessageText.getString("label.learnmore") + "</A>");
-					fd = new FormData();
-					fd.left = new FormAttachment(button, 10);
-					fd.top = new FormAttachment(button, 0, SWT.CENTER);
-					lblLearnMore.setLayoutData(fd);
-					lblLearnMore.addSelectionListener(new SelectionAdapter() {
-						public void widgetSelected(SelectionEvent e) {
-							Utils.launch(e.text);
-						}
-					});
-				}
-			}
-		}
-
-		dlg.addCloseListener(new SkinnedDialogClosedListener() {
-			public void skinDialogClosed(SkinnedDialog dialog) {
-			}
-		});
-
-		dlg.open();
-		soButton.getControl().setFocus();
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/utils/ImageResizer.java b/com/aelitis/azureus/ui/swt/utils/ImageResizer.java
index a9385db..e976c85 100644
--- a/com/aelitis/azureus/ui/swt/utils/ImageResizer.java
+++ b/com/aelitis/azureus/ui/swt/utils/ImageResizer.java
@@ -13,6 +13,7 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AEThread;
 import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 
 public class ImageResizer
 {
@@ -106,6 +107,8 @@ public class ImageResizer
 		}
 	};
 
+	private ImageResizerListener imageResizerListener;
+
 	public ImageResizer(Display display, int width, int height, Shell parent) {
 		this.parent = parent;
 		this.display = display;
@@ -113,9 +116,10 @@ public class ImageResizer
 		this.minHeight = height;
 	}
 
-	public Image resize(Image original) throws ImageResizeException {
+	public void resize(Image original, ImageResizerListener l) throws ImageResizeException {
 
 		this.original = original;
+		this.imageResizerListener = l;
 
 		//If the image is too small, let's just not deal with it
 		if (!checkSize(original)) {
@@ -148,18 +152,10 @@ public class ImageResizer
 			initUI();
 
 			done = false;
-			while (!done) {
-				if (!display.readAndDispatch()) {
-					display.sleep();
-				}
-			}
 		} else {
 			result = computeResultImage();
+			l.imageResized(result);
 		}
-
-		dispose();
-
-		return result;
 	}
 
 	private void initUI() {
@@ -167,9 +163,9 @@ public class ImageResizer
 		cursor = new Cursor(display, SWT.CURSOR_HAND);
 
 		if (parent != null) {
-			shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+			shell = ShellFactory.createShell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
 		} else {
-			shell = new Shell(display, SWT.CLOSE | SWT.BORDER);
+			shell = ShellFactory.createMainShell(SWT.CLOSE | SWT.BORDER);
 		}
 		shell.setText("Thumbnail Assistant");
 
@@ -180,6 +176,9 @@ public class ImageResizer
 				event.doit = false;
 				result = null;
 				done = true;
+				shell = null;
+				dispose();
+				imageResizerListener.imageResized(result);
 			}
 		});
 
@@ -301,6 +300,8 @@ public class ImageResizer
 			public void handleEvent(Event arg0) {
 				result = null;
 				done = true;
+				dispose();
+				imageResizerListener.imageResized(result);
 			}
 		});
 
@@ -315,6 +316,8 @@ public class ImageResizer
 			public void handleEvent(Event arg0) {
 				result = computeResultImage();
 				done = true;
+				dispose();
+				imageResizerListener.imageResized(result);
 			}
 		});
 
@@ -582,21 +585,28 @@ public class ImageResizer
 			drawCurrentImage();
 		}
 	}
+	
+	public interface ImageResizerListener {
+		void imageResized(Image image);
+	}
 
-	public static void main(String args[]) throws Exception {
-		Display display = Display.getDefault();
-		Shell test = new Shell(display);
+	public static void main(final String args[]) throws Exception {
+		final Display display = Display.getDefault();
+		final Shell test = new Shell(display);
 		ImageResizer resizer = new ImageResizer(display, 228, 128, null);
 		String file = new FileDialog(test).open();
 		Image img = new Image(display, file);
-		Image thumbnail = resizer.resize(img);
-
-		System.out.println(thumbnail);
+		resizer.resize(img, new  ImageResizerListener() {
+			public void imageResized(Image thumbnail) {
+				System.out.println(thumbnail);
+				
+				thumbnail.dispose();
+				test.dispose();
+				if (args.length == 0) {
+					display.dispose();
+				}
+			}
+		});
 
-		thumbnail.dispose();
-		test.dispose();
-		if (args.length == 0) {
-			display.dispose();
-		}
 	}
 }
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/swt/utils/PublishUtils.java b/com/aelitis/azureus/ui/swt/utils/PublishUtils.java
deleted file mode 100644
index 70b1258..0000000
--- a/com/aelitis/azureus/ui/swt/utils/PublishUtils.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.aelitis.azureus.ui.swt.utils;
-
-import com.aelitis.azureus.core.messenger.ClientMessageContext;
-import com.aelitis.azureus.ui.swt.browser.listener.publish.PublishTransaction;
-import com.aelitis.azureus.ui.swt.browser.listener.publish.SeedingListener;
-
-/**
- * Publish functions that are used by both the Publisher plugin and AZ3ui's publish window
- * 
- * @author TuxPaper
- *
- */
-public class PublishUtils
-{
-	public static void setupContext(ClientMessageContext context) {
-		context.registerTransactionType("publish", PublishTransaction.class);
-		context.addMessageListener(new SeedingListener());
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/utils/SWTLoginUtils.java b/com/aelitis/azureus/ui/swt/utils/SWTLoginUtils.java
deleted file mode 100644
index e348555..0000000
--- a/com/aelitis/azureus/ui/swt/utils/SWTLoginUtils.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * Created on May 6, 2008
- *
- * Copyright 2008 Vuze, Inc.  All rights reserved.
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License only.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
- */
-
-package com.aelitis.azureus.ui.swt.utils;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.ui.swt.Utils;
-
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.ui.swt.shells.LightBoxBrowserWindow;
-import com.aelitis.azureus.util.*;
-import com.aelitis.azureus.util.LoginInfoManager.LoginInfo;
-
-/**
- * @author TuxPaper
- * @created May 6, 2008
- *
- */
-public class SWTLoginUtils
-{
-	public static void waitForLogin(final loginWaitListener l) {
-		VuzeBuddyManager.log("Wait for login " + l);
-		if (l == null) {
-			return;
-		}
-
-		final AERunnable loginCompleteRunnable = new AERunnable() {
-			public void runSupport() {
-				VuzeBuddyManager.log("Fire Login Complete");
-				l.loginComplete();
-			}
-		};
-
-		final AERunnable loginCancelRunnable = new AERunnable() {
-			public void runSupport() {
-				VuzeBuddyManager.log("Fire Login Cancel");
-				l.loginCanceled();
-			}
-		};
-
-		final LoginInfoManager loginManager = LoginInfoManager.getInstance();
-		if (loginManager.isLoggedIn()) {
-			Utils.execSWTThread(loginCompleteRunnable);
-			return;
-		}
-
-		final ILoginInfoListener loginInfoListener = new ILoginInfoListener() {
-			public void loginUpdate(LoginInfo info, boolean isNewLoginID) {
-				if (loginManager.isLoggedIn()) {
-					loginManager.removeListener(this);
-					Utils.execSWTThread(loginCompleteRunnable);
-				}
-			}
-
-			// @see com.aelitis.azureus.util.ILoginInfoListener#avatarURLUpdated()
-			public void avatarURLUpdated(String newAvatarURL) {
-			}
-		};
-
-		loginManager.addListener(loginInfoListener);
-		LightBoxBrowserWindow loginWindow = openLoginWindow(l.getOptionalMessage());
-		loginWindow.setCloseListener(new LightBoxBrowserWindow.closeListener() {
-			public void close() {
-				SimpleTimer.addEvent("cancel login wait",
-						SystemTime.getOffsetTime(l.getCancelDelay()),
-						new TimerEventPerformer() {
-							public void perform(TimerEvent event) {
-								loginManager.removeListener(loginInfoListener);
-								if (!loginManager.isLoggedIn()) {
-									Utils.execSWTThread(loginCancelRunnable);
-								}
-							}
-						});
-			}
-		});
-	}
-
-	/**
-	 * 
-	 * @return
-	 * @since 3.0.5.3
-	 */
-	public static LightBoxBrowserWindow openLoginWindow() {
-		return openLoginWindow(null);
-	}
-
-	/**
-	 * 
-	 * @param optionalMessage an optional message to display in the Sign In window
-	 * @return
-	 * @since 3.0.5.3
-	 */
-	public static LightBoxBrowserWindow openLoginWindow(String optionalMessage) {
-		VuzeBuddyManager.log("Open Login Window: msg=" + optionalMessage);
-		String url = ConstantsVuze.getDefaultContentNetwork().getLoginService( optionalMessage );
-
-		return new LightBoxBrowserWindow(url, ConstantsVuze.URL_PAGE_VERIFIER_VALUE,
-				380, 280);
-	}
-
-	public static abstract class loginWaitListener
-	{
-
-		private String message = null;
-
-		/**
-		 * The milliseconds to wait before firing off a cancel event
-		 */
-		private long cancelDelay;
-
-		/**
-		 * This will be on the SWT thread
-		 *
-		 * @since 3.0.5.3
-		 */
-		public abstract void loginComplete();
-
-		public loginWaitListener() {
-			init();
-		}
-
-		public void init() {
-			cancelDelay = 10000;
-		}
-
-		public String getOptionalMessage() {
-			if (null == message) {
-				message = MessageText.getString("login.optional.message");
-			}
-			return message;
-		}
-
-		public void loginCanceled() {
-		}
-
-		public long getCancelDelay() {
-			return cancelDelay;
-		}
-
-		public void setCancelDelay(long cancelDelay) {
-			this.cancelDelay = cancelDelay;
-		};
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/utils/TorrentUIUtilsV3.java b/com/aelitis/azureus/ui/swt/utils/TorrentUIUtilsV3.java
index 2376c17..480c8f1 100644
--- a/com/aelitis/azureus/ui/swt/utils/TorrentUIUtilsV3.java
+++ b/com/aelitis/azureus/ui/swt/utils/TorrentUIUtilsV3.java
@@ -22,7 +22,6 @@ package com.aelitis.azureus.ui.swt.utils;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
-import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -46,10 +45,11 @@ import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.ui.swt.*;
 import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
 import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.UIFunctionsManager;
@@ -128,12 +128,12 @@ public class TorrentUIUtilsV3
 
 						}.start();
 					} else {
-						Utils.openMessageBox(Utils.findAnyShell(), SWT.OK,
+						new MessageBoxShell(SWT.OK,
 								MSG_ALREADY_EXISTS, new String[] {
 									" ",
 									dm.getDisplayName(),
 									MessageText.getString(MSG_ALREADY_EXISTS_NAME),
-								});
+								}).open(null);
 					}
 					return;
 				}
@@ -280,18 +280,13 @@ public class TorrentUIUtilsV3
 						return;
 					}
 
-					boolean showHomeHint = true;
 					if (playNow || playPrepare) {
 						if (playNow) {
-							showHomeHint = !TorrentListViewsUtils.playOrStream(dm);
+							TorrentListViewsUtils.playOrStream(dm);
 						} else {
 							PlayUtils.prepareForPlay(dm);
-							showHomeHint = false;
 						}
 					}
-					if (showHomeHint) {
-						TorrentListViewsUtils.showHomeHint(dm);
-					}
 				} catch (Exception e) {
 					Debug.out(e);
 				}
@@ -342,7 +337,7 @@ public class TorrentUIUtilsV3
 	 *
 	 * @since 4.0.0.5
 	 */
-	public static Image getContentImage(Object datasource, boolean big,
+	public static Image[] getContentImage(Object datasource, boolean big,
 			final ContentImageLoadedListener l) {
 		if (l == null) {
 			return null;
@@ -353,13 +348,16 @@ public class TorrentUIUtilsV3
 			return null;
 		}
 
-		ImageLoader imageLoader = ImageLoader.getInstance();
+		final ImageLoader imageLoader = ImageLoader.getInstance();
 
 		String thumbnailUrl = PlatformTorrentUtils.getContentThumbnailUrl(torrent);
 
+		//System.out.println("thumburl= " + thumbnailUrl);
 		if (thumbnailUrl != null && imageLoader.imageExists(thumbnailUrl)) {
-			l.contentImageLoaded(imageLoader.getImage(thumbnailUrl), true);
-			return null;
+			//System.out.println("return thumburl");
+			Image image = imageLoader.getImage(thumbnailUrl);
+			l.contentImageLoaded(image, true);
+			return new Image[] { image };
 		}
 
 		String hash = null;
@@ -372,15 +370,17 @@ public class TorrentUIUtilsV3
 			return null;
 		}
 
-		String id = "Thumbnail." + hash;
+		final String id = "Thumbnail." + hash;
 
 		Image image = imageLoader.imageAdded(id) ? imageLoader.getImage(id) : null;
+		//System.out.println("image = " + image);
 		if (image != null && !image.isDisposed()) {
 			l.contentImageLoaded(image, true);
-			return image;
+			return new Image[] { image };
 		}
 
 		final byte[] imageBytes = PlatformTorrentUtils.getContentThumbnail(torrent);
+		//System.out.println("imageBytes = " + imageBytes);
 		if (imageBytes != null) {
 			image = (Image) Utils.execSWTThreadWithObject("thumbcreator",
 					new AERunnableObject() {
@@ -394,15 +394,19 @@ public class TorrentUIUtilsV3
 					}, 500);
 		}
 		if ((image == null || image.isDisposed()) && thumbnailUrl != null) {
+			//System.out.println("get image from " + thumbnailUrl);
 			image = imageLoader.getUrlImage(thumbnailUrl,
 					new ImageDownloaderListener() {
 						public void imageDownloaded(Image image, boolean returnedImmediately) {
 							l.contentImageLoaded(image, returnedImmediately);
+							//System.out.println("got image from thumburl");
 						}
 					});
-			return image;
+			//System.out.println("returning " + image + " (url loading)");
+			return new Image[] { image };
 		}
 		if (image == null || image.isDisposed()) {
+			//System.out.println("build image from files");
 			DownloadManager dm = DataSourceUtils.getDM(datasource);
 			/*
 			 * Try to get an image from the OS
@@ -420,11 +424,14 @@ public class TorrentUIUtilsV3
 				path = dm.getDownloadState().getPrimaryFile();
 			}
 			if (path != null) {
-				// Don't ever dispose of PathIcon, it's cached and may be used elsewhere
-				Image icon = ImageRepository.getPathIcon(path, big, torrent != null
-						&& !torrent.isSimpleTorrent());
-				if (icon != null) {
-					image = new Image(Display.getDefault(), icon, SWT.IMAGE_COPY);
+				image = ImageRepository.getPathIcon(path, big, false);
+				
+				if (image != null && torrent != null && !torrent.isSimpleTorrent()) {
+					Image[] images = new Image[] {
+						image,
+						ImageRepository.getPathIcon(new File(path).getParent(), false, false)
+					};
+					return images;
 				}
 			}
 
@@ -434,11 +441,12 @@ public class TorrentUIUtilsV3
 				imageLoader.addImage(id, image);
 			}
 		} else {
+			//System.out.println("has mystery image");
 			imageLoader.addImage(id, image);
 		}
 
 		l.contentImageLoaded(image, true);
-		return image;
+		return new Image[] { image };
 	}
 
 	public static void releaseContentImage(Object datasource) {
diff --git a/com/aelitis/azureus/ui/swt/utils/UIMagnetHandler.java b/com/aelitis/azureus/ui/swt/utils/UIMagnetHandler.java
index 0884109..d031798 100644
--- a/com/aelitis/azureus/ui/swt/utils/UIMagnetHandler.java
+++ b/com/aelitis/azureus/ui/swt/utils/UIMagnetHandler.java
@@ -32,6 +32,7 @@ import com.aelitis.azureus.plugins.magnet.MagnetPlugin;
 import com.aelitis.azureus.plugins.magnet.MagnetPluginListener;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 import com.aelitis.net.magneturi.MagnetURIHandler;
 
 import org.gudy.azureus2.plugins.PluginInterface;
@@ -115,16 +116,19 @@ public class UIMagnetHandler
 		Utils.execSWTThreadLater(0, new AERunnable() {
 			public void runSupport() {
 				uif.bringToFront();
-				int i = uif.promptUser(MessageText.getString("dialog.uiswitch.title"),
+				uif.promptUser(MessageText.getString("dialog.uiswitch.title"),
 						MessageText.getString("dialog.uiswitch.text"), new String[] {
 							MessageText.getString("dialog.uiswitch.button"),
-						}, 0, null, null, false, 0);
-				if (i != 0) {
-					return;
-				}
-				COConfigurationManager.setParameter("ui", "az3");
-				COConfigurationManager.save();
-				core.requestRestart();
+						}, 0, null, null, false, 0, new UserPrompterResultListener() {
+							public void prompterClosed(int returnVal) {
+								if (returnVal != 0) {
+									return;
+								}
+								COConfigurationManager.setParameter("ui", "az3");
+								COConfigurationManager.save();
+								core.requestRestart();
+							}
+						});
 			}
 		});
 	}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/AvatarWidget.java b/com/aelitis/azureus/ui/swt/views/skin/AvatarWidget.java
deleted file mode 100644
index 9386395..0000000
--- a/com/aelitis/azureus/ui/swt/views/skin/AvatarWidget.java
+++ /dev/null
@@ -1,1658 +0,0 @@
-package com.aelitis.azureus.ui.swt.views.skin;
-
-import java.io.File;
-import java.net.URL;
-import java.text.SimpleDateFormat;
-import java.util.*;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.*;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.category.Category;
-import org.gudy.azureus2.core3.category.CategoryManager;
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.global.GlobalManager;
-import org.gudy.azureus2.core3.internat.LocaleTorrentUtil;
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.torrent.*;
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.ui.swt.*;
-import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
-import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
-
-import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.chat.ChatDiscussion;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.messenger.config.PlatformBuddyMessenger;
-import com.aelitis.azureus.core.messenger.config.VuzeBuddySyncListener;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentV3;
-import com.aelitis.azureus.ui.skin.SkinConstants;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.buddy.VuzeBuddySWT;
-import com.aelitis.azureus.ui.swt.buddy.chat.impl.ChatWindow;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.shells.friends.SharePage;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-import com.aelitis.azureus.util.LoginInfoManager;
-
-public class AvatarWidget
-{
-	private static final boolean SHOW_ONLINE_BORDER = System.getProperty(
-			"az.buddy.show_online", "1").equals("1");
-
-	protected static final boolean OLD_DRAWNAME = false;
-
-	private Canvas canvas = null;
-
-	private BuddiesViewer viewer = null;
-
-	private Composite parent = null;
-
-	private int highlightBorder = 0;
-
-	private int imageBorder = 1;
-
-	private Point imageSize = null;
-
-	private Point size = null;
-
-	private Point nameAreaSize = null;
-
-	private Rectangle imageBounds = null;
-
-	private Rectangle nameAreaBounds = null;
-
-	private Rectangle chatAreaBounds = null;
-	
-	private Rectangle subsAreaBounds = null;
-
-	private VuzeBuddySWT vuzeBuddy = null;
-
-	private boolean isActivated = false;
-
-	private boolean isSelected = false;
-
-	private boolean isEnabled = true;
-
-	private boolean isDisposing = false;
-
-	private boolean nameLinkActive = false;
-
-	private Color textColor = null;
-	
-	private Color selectedTextColor = null;
-
-	private Color textLinkColor = null;
-
-	private Color imageBorderColor = null;
-
-	private Color selectedColor = null;
-
-	private Color highlightedColor = null;
-
-	private Rectangle decorator_remove_friend = null;
-
-	private Rectangle decorator_add_to_share = null;
-
-	private int alpha = 255;
-
-	private boolean sharedAlready = false;
-
-	private Menu menu;
-
-	private static Font fontDisplayName;
-
-	private String tooltip_remove_friend;
-
-	private String tooltip_add_to_share;
-
-	private String tooltip;
-
-	private Image removeImage = null;
-
-	private Image add_to_share_Image = null;
-
-	private Image removeImage_normal = null;
-
-	private Image add_to_share_Image_normal = null;
-
-	//private Image removeImage_over = null;
-
-	//private Image add_to_share_Image_over = null;
-
-	private boolean isDragging = false;
-
-	private Image add_to_share_Image_selected = null;
-
-	private boolean isCreatingFile = false;
-
-	private int creationPercent = 0;
-
-	private ChatWindow chatWindow;
-
-	private ChatDiscussion discussion;
-
-	private SharePage sharePage = null;
-	
-	public AvatarWidget(BuddiesViewer viewer, Point avatarSize,
-			Point avatarImageSize, Point avatarNameSize, VuzeBuddySWT vuzeBuddy) {
-
-		if (null == viewer || null == vuzeBuddy) {
-			throw new NullPointerException(
-					"The variable 'viewer' and 'vuzeBuddy' can not be null");
-		}
-
-		this.viewer = viewer;
-
-		if (null == viewer.getControl() || true == viewer.getControl().isDisposed()) {
-			throw new NullPointerException(
-					"The given 'viewer' is not properly initialized");
-		}
-
-		this.parent = viewer.getControl();
-		this.size = avatarSize;
-		this.imageSize = avatarImageSize;
-		this.nameAreaSize = avatarNameSize;
-		this.vuzeBuddy = vuzeBuddy;
-		canvas = new Canvas(parent, SWT.NONE | SWT.DOUBLE_BUFFERED);
-		canvas.setData("AvatarWidget", this);
-
-		init();
-	}
-
-	private void init() {
-
-		final ImageLoader imageLoader = ImageLoader.getInstance();
-		removeImage_normal = imageLoader.getImage("image.buddy.remove");
-		add_to_share_Image_normal = imageLoader.getImage("image.buddy.add.to.share");
-		//removeImage_over = imageLoader.getImage("image.buddy.remove-over");
-		add_to_share_Image_selected = imageLoader.getImage("image.buddy.add.to.share-selected");
-
-		removeImage = removeImage_normal;
-		add_to_share_Image = add_to_share_Image_normal;
-
-		tooltip_remove_friend = MessageText.getString("v3.buddies.remove");
-		tooltip_add_to_share = MessageText.getString("v3.buddies.add.to.share");
-		tooltip = vuzeBuddy.getDisplayName() + " (" + vuzeBuddy.getLoginID() + ")";
-
-		/*
-		 * Centers the image and name horizontally
-		 */
-		imageBounds = new Rectangle((size.x / 2) - (imageSize.x / 2), 8,
-				imageSize.x, imageSize.y);
-
-		nameAreaBounds = new Rectangle((size.x / 2) - ((nameAreaSize.x - 6) / 2),
-				imageBounds.y + imageBounds.height + 2, nameAreaSize.x - 6,
-				nameAreaSize.y);
-
-		/*
-		 * Position the decorator icons
-		 */
-		decorator_remove_friend = new Rectangle(size.x
-				- (highlightBorder + imageBorder) - 12 - 1, highlightBorder
-				+ imageBorder + 1, 12, 12);
-
-		decorator_add_to_share = new Rectangle(highlightBorder + imageBorder + 1,
-				highlightBorder + imageBorder + 1, 12, 12);
-
-		int operations = DND.DROP_COPY;
-		Transfer[] types = new Transfer[] {
-			FileTransfer.getInstance(),
-			TextTransfer.getInstance(),
-		};
-		DropTarget target = new DropTarget(canvas, operations);
-		target.setTransfer(types);
-
-		target.addDropListener(new DropTargetListener() {
-			public void dragEnter(DropTargetEvent event) {
-				if (FileTransfer.getInstance().isSupportedType(event.currentDataType)) {
-  				if (isCreatingFile) {
-  					event.detail = DND.DROP_NONE;
-  				} else {
-  					event.detail = DND.DROP_COPY;
-  					isDragging = true;
-  				}
-				} else {
-					event.detail = DND.DROP_COPY;
-					isDragging = true;
-				}
-			};
-
-			public void dragOver(DropTargetEvent event) {
-			};
-
-			public void dragLeave(DropTargetEvent event) {
-				isDragging = false;
-			};
-
-			public void dragOperationChanged(DropTargetEvent event) {
-			};
-
-			public void dropAccept(DropTargetEvent event) {
-			}
-
-			public void drop(DropTargetEvent event) {
-				isDragging = false;
-				// A drop has occurred, copy over the data
-				if (event.data == null) { // no data to copy, indicate failure in event.detail
-					event.detail = DND.DROP_NONE;
-					return;
-				}
-				
-				if (!FileTransfer.getInstance().isSupportedType(event.currentDataType)) {
-  				if ((event.data instanceof String) && ((String)event.data).startsWith("DownloadManager\n")) {
-  					String[] hashes = ((String)event.data).split("\n");
-  					GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
-  					
-  					if (hashes.length > 1) {
-    					for (int i = 1; i < hashes.length; i++) {
-    						String hash = hashes[i];
-    						DownloadManager dm = gm.getDownloadManager(new HashWrapper(Base32.decode(hash)));
-    						if (dm != null) {
-    							try {
-										SelectedContentV3 sc = new SelectedContentV3(dm);
-	    							VuzeShareUtils.getInstance().shareContent(sc, new VuzeBuddy[] { vuzeBuddy }, "drop");
-	    							break; // can only share one at a time :(
-									} catch (Exception e) {
-									}
-    						}
-    					}
-  					}
-  				}
-					return;
-				}
-				
-				String[] files = null;
-				if (event.data instanceof String[]) {
-					files = (String[]) event.data;
-				} else if (event.data instanceof String) {
-					files = new String[] {
-						(String) event.data
-					};
-				}
-				if (files != null) {
-					if (files.length == 1) {
-						try {
-							if (!isCreatingFile) {
-
-								MessageBoxShell mb = new MessageBoxShell(
-										canvas.getShell(),
-										MessageText.getString("v3.buddies.dnd.info.dialog.title"),
-										MessageText.getString("v3.buddies.dnd.info.dialog.text"),
-										new String[] {
-											MessageText.getString("v3.buddies.dnd.info.dialog.ok"),
-										},
-										0,
-										"v3.buddies.dnd.info",
-										MessageText.getString("v3.buddies.dnd.info.dialog.remember"),
-										false, 0);
-
-								int result = mb.open();
-								if (result != 0) {
-									return;
-								}
-
-								creationPercent = 0;
-								isCreatingFile = true;
-								final File file = new File(files[0]);
-								final TOTorrentCreator creator = TOTorrentFactory.createFromFileOrDirWithComputedPieceLength(
-										file, new URL("dht:"), false);
-								creator.addListener(new TOTorrentProgressListener() {
-									public void reportCurrentTask(String task_description) {
-
-									}
-
-									public void reportProgress(int percent_complete) {
-										creationPercent = percent_complete;
-
-										if (!canvas.isDisposed()) {
-											canvas.getDisplay().asyncExec(new Runnable() {
-												public void run() {
-													canvas.redraw();
-												};
-											});
-										}
-
-									}
-
-								});
-
-								new AEThread2("DNDBuddy::Share", true) {
-
-									public void run() {
-										try {
-											TOTorrent torrent = creator.create();
-											TorrentUtils.setDecentralised(torrent);
-											TorrentUtils.setDHTBackupEnabled(torrent, true);
-											LocaleTorrentUtil.setDefaultTorrentEncoding(torrent);
-
-											File v3Shares = new File(SystemProperties.getUserPath(),
-													"v3shares");
-											if (!v3Shares.exists()) {
-												v3Shares.mkdirs();
-											}
-
-											TorrentUtils.setFlag(torrent,
-													TorrentUtils.TORRENT_FLAG_LOW_NOISE, true);
-
-											final File torrent_file = new File(v3Shares,
-													file.getName() + ".torrent");
-											torrent.serialiseToBEncodedFile(torrent_file);
-
-											byte[] hash = null;
-											try {
-												hash = torrent.getHash();
-											} catch (TOTorrentException e1) {
-											}
-
-											final DownloadManager dm = AzureusCoreFactory.getSingleton().getGlobalManager().addDownloadManager(
-													torrent_file.getAbsolutePath(), hash,
-													file.getAbsolutePath(), DownloadManager.STATE_QUEUED,
-													true, // persistent 
-													true, // for seeding
-													null); // no adapter required
-
-											dm.getDownloadState().setFlag(
-													Download.FLAG_DO_NOT_DELETE_DATA_ON_REMOVE, true);
-
-											if (!canvas.isDisposed()) {
-												canvas.getDisplay().asyncExec(new Runnable() {
-													public void run() {
-														try {
-															SelectedContentV3 sc = new SelectedContentV3(dm);
-															VuzeShareUtils.getInstance().shareContent(sc,
-																	new VuzeBuddy[] {
-																		vuzeBuddy
-																	}, "buddy-dnd");
-														} catch (Exception e) {
-															e.printStackTrace();
-														}
-													}
-												});
-											}
-
-										} catch (Exception e) {
-											e.printStackTrace();
-										} finally {
-											isCreatingFile = false;
-										}
-									}
-								}.start();
-							}
-
-						} catch (Exception e) {
-							e.printStackTrace();
-							isCreatingFile = false;
-						}
-
-						canvas.redraw();
-					} else {
-
-						MessageBoxShell mb = new MessageBoxShell(canvas.getShell(),
-								MessageText.getString("v3.buddies.dnd.multifile.dialog.title"),
-								MessageText.getString("v3.buddies.dnd.multifile.dialog.text"),
-								new String[] {
-									MessageText.getString("v3.buddies.dnd.multifile.dialog.ok"),
-								}, 0);
-						mb.open();
-					}
-				}
-			}
-		});
-
-		canvas.addPaintListener(new PaintListener() {
-
-			public void paintControl(PaintEvent e) {
-				if (false == isFullyVisible()) {
-					return;
-				}
-
-				/*if (fontDisplayName == null || fontDisplayName.isDisposed()) {
-					fontDisplayName = Utils.getFontWithHeight(canvas.getFont(), e.gc, 12);
-					e.gc.setFont(fontDisplayName);
-				}*/
-
-				try {
-					e.gc.setAntialias(SWT.ON);
-					
-					e.gc.setAlpha(getAlpha());
-					e.gc.setInterpolation(SWT.HIGH);
-					//e.gc.setTextAntialias(SWT.ON);
-				} catch (Exception ex) {
-					// ignore.. some of these may not be avail
-				}
-
-				Rectangle bounds = canvas.getBounds();
-				if(isActivated) {
-					e.gc.setForeground(highlightedColor);
-					e.gc.drawRoundRectangle(highlightBorder, highlightBorder,
-							bounds.width - (2 * highlightBorder)-1, bounds.height
-									- (2 * highlightBorder)-1, 6, 6);
-					
-				}
-				
-				nameAreaBounds = new Rectangle(2,
-						imageBounds.y + imageBounds.height + 2, bounds.width - 2,
-						nameAreaSize.y);
-
-				
-				/*
-				 * Draw background if the widget is activated or selected
-				 */
-				
-				/*if (true == isSelected && selectedColor != null) {
-					e.gc.setBackground(selectedColor);
-					Rectangle bounds = canvas.getBounds();
-					e.gc.fillRoundRectangle(highlightBorder, highlightBorder,
-							bounds.width - (2 * highlightBorder), bounds.height
-									- (2 * highlightBorder), 6, 6);
-					e.gc.setBackground(canvas.getBackground());
-				}*/
-
-				/*
-				 * Draw highlight borders if the widget is activated (being hovered over)
-				 */
-
-				Image imgAvatar = vuzeBuddy.getAvatarImage();
-
-				/*
-				 * Draw the avatar image
-				 */
-				if (null == imgAvatar || imgAvatar.isDisposed()) {
-					/*
-					 * Paint nothing if the buddy has no avatar AND the default image is not found,
-					 * OR the image has been disposed
-					 */
-					Debug.out("No avatar image found and no default image supplies?");
-				} else {
-					Rectangle sourceImageBounds = imgAvatar.getBounds();
-
-					if (true == viewer.isEditMode()) {
-						e.gc.setAlpha((int) (getAlpha() * .7));
-						/*
-						 * Image
-						 */
-						int x = (bounds.width - imageBounds.width) / 2;
-						int y = imageBounds.y;
-						e.gc.drawImage(imgAvatar, 0, 0, sourceImageBounds.width,
-								sourceImageBounds.height, x, y,
-								imageBounds.width, imageBounds.height);
-						e.gc.setAlpha(getAlpha());
-						/*
-						 * Image border
-						 */
-						if (imageBorder > 0 && imageBorderColor != null) {
-							e.gc.setForeground(imageBorderColor);
-							e.gc.setLineWidth(imageBorder);
-							e.gc.drawRectangle(x - imageBorder, y
-									- imageBorder, imageBounds.width + imageBorder,
-									imageBounds.height + imageBorder);
-							e.gc.setForeground(canvas.getForeground());
-						}
-					} else {
-						/*
-						 * Image
-						 */
-						int x = (bounds.width - imageBounds.width) / 2;
-						int y = imageBounds.y;
-						e.gc.drawImage(imgAvatar, 0, 0, sourceImageBounds.width,
-								sourceImageBounds.height, x, y,
-								imageBounds.width, imageBounds.height);
-						/*
-						 * Image border
-						 */
-						if (imageBorder > 0 && imageBorderColor != null) {
-							e.gc.setForeground(imageBorderColor);
-							e.gc.setLineWidth(imageBorder);
-							e.gc.drawRectangle(x - imageBorder, y
-									- imageBorder, imageBounds.width + imageBorder,
-									imageBounds.height + imageBorder);
-							e.gc.setForeground(canvas.getForeground());
-						}
-					}
-				}
-				
-				vuzeBuddy.releaseAvatarImage(imgAvatar);
-
-				if (isSharedAlready()) {
-					add_to_share_Image = add_to_share_Image_selected;
-				} else {
-					add_to_share_Image = add_to_share_Image_normal;
-				}
-
-				/*
-				 * Draw decorator
-				 */
-				if (true == viewer.isEditMode()) {
-					e.gc.drawImage(removeImage, 0, 0, removeImage.getBounds().width,
-							removeImage.getBounds().height, decorator_remove_friend.x,
-							decorator_remove_friend.y, decorator_remove_friend.width,
-							decorator_remove_friend.height);
-				} else if (true == viewer.isShareMode()) {
-					e.gc.drawImage(add_to_share_Image, 0, 0,
-							add_to_share_Image.getBounds().width, add_to_share_Image.getBounds().height,
-							decorator_add_to_share.x, decorator_add_to_share.y,
-							decorator_add_to_share.width, decorator_add_to_share.height);
-				}
-
-				/*
-				 * Draw the buddy display name
-				 */
-
-				if (true == nameLinkActive && true == isActivated) {
-					e.gc.setForeground(textLinkColor == null ? canvas.getForeground()
-							: textLinkColor);
-					if (false == isDragging) {
-						canvas.setCursor(canvas.getDisplay().getSystemCursor(
-								SWT.CURSOR_HAND));
-					}
-				} else {
-					if (false == isDragging) {
-						canvas.setCursor(null);
-					}
-					e.gc.setForeground(textColor == null ? canvas.getForeground()
-							: textColor);
-				}
-
-				/*
-				 * The multi-line display of name is disabled for now 
-				 */
-				//					int flags = SWT.CENTER | SWT.WRAP;
-				//					GCStringPrinter stringPrinter = new GCStringPrinter(e.gc,
-				//							vuzeBuddy.getDisplayName(), avatarNameBounds, false, true, flags);
-				//					stringPrinter.calculateMetrics();
-				//
-				//					if (stringPrinter.isCutoff()) {
-				//						e.gc.setFont(fontDisplayName);
-				//						avatarNameBounds.height += 9;
-				//						avatarNameBounds.y -= 4;
-				//					}
-				//					stringPrinter.printString(e.gc, avatarNameBounds, SWT.CENTER);
-				//					e.gc.setFont(null);
-				if (!isCreatingFile) {
-					e.gc.setFont(fontDisplayName);
-
-					if (OLD_DRAWNAME) {
-  					int width = 0;
-  					String displayName = vuzeBuddy.getDisplayName();
-  					StringBuffer displayed = new StringBuffer();
-  
-  					Image icon = null;
-  
-  					if (SHOW_ONLINE_BORDER && vuzeBuddy.isOnline(true)) {
-  						icon = ImageLoader.getInstance().getImage("friend_online_icon");
-  						width += icon.getBounds().width + 3;
-  					}
-  
-  					int dotWidth = e.gc.getAdvanceWidth('.');
-  					int maxWidth = nameAreaBounds.width;
-  
-  					for (int i = 0; i < displayName.length() && width < maxWidth; i++) {
-  						char nextChar = displayName.charAt(i);
-  						int extraWidth = e.gc.getAdvanceWidth(nextChar);
-  						if (width + 2 * dotWidth >= maxWidth) {
-  							//We only have room for 2 dot characters, let's simply check if we're processing the last one,
-  							// and if it fits in
-  							if (i == displayName.length() - 1
-  									&& (width + extraWidth <= maxWidth)) {
-  								displayed.append(nextChar);
-  								width += extraWidth;
-  							} else {
-  								displayed.append("..");
-  								width += 2 * dotWidth;
-  							}
-  						} else {
-  							displayed.append(nextChar);
-  							width += extraWidth;
-  						}
-  					}
-  
-  					int offset = (maxWidth - width) / 2;
-  					if (icon != null) {
-  						e.gc.drawImage(icon, offset + nameAreaBounds.x,
-  								nameAreaBounds.y + 1);
-  						offset += icon.getBounds().width + 1;
-  						ImageLoader.getInstance().releaseImage("friend_online_icon");
-  					}
-  
-  					e.gc.drawText(displayed.toString(), offset + nameAreaBounds.x,
-  							nameAreaBounds.y + 1, true);
-  
-  					//e.gc.fillRectangle(nameAreaBounds);
-					} else {
-
-						e.gc.setForeground(textLinkColor);
-						
-						if (SHOW_ONLINE_BORDER && vuzeBuddy.isOnline(true)) {
-							GCStringPrinter stringPrinter = new GCStringPrinter(e.gc, "%0 "
-									+ vuzeBuddy.getDisplayName(), nameAreaBounds, false, false,
-									SWT.TOP | SWT.CENTER | SWT.WRAP);
-							stringPrinter.setImages(new Image[] {
-								ImageLoader.getInstance().getImage("friend_online_icon")
-							});
-							stringPrinter.printString();
-							ImageLoader.getInstance().releaseImage("friend_online_icon");
-						} else {
-							GCStringPrinter.printString(e.gc, vuzeBuddy.getDisplayName(),
-									nameAreaBounds, false, false, SWT.TOP | SWT.CENTER | SWT.WRAP);
-						}
-					}
-
-				} else {
-
-					Rectangle progressArea = new Rectangle(nameAreaBounds.x + 5,
-							nameAreaBounds.y + 5, nameAreaBounds.width - 10,
-							nameAreaBounds.height - 10);
-					e.gc.setForeground(viewer.getColorFileDragBorder());
-					e.gc.drawRectangle(progressArea.x, progressArea.y,
-							progressArea.width, progressArea.height);
-					progressArea.x += 1;
-					progressArea.y += 1;
-					progressArea.height -= 1;
-					progressArea.width = creationPercent * (progressArea.width - 1) / 100;
-					e.gc.setBackground(viewer.getColorFileDragBG());
-					e.gc.fillRectangle(progressArea.x, progressArea.y,
-							progressArea.width, progressArea.height);
-				}
-
-				if (chatWindow != null && chatWindow.isDisposed()) {
-					chatWindow = null;
-				}
-
-				boolean showChatIcon = !viewer.isEditMode()
-						&& discussion != null
-						&& ((chatWindow != null && !chatWindow.isDisposed() && discussion.getNbMessages() > 0) || (discussion.getUnreadMessages() > 0));
-
-				if (showChatIcon) {
-					chatAreaBounds = new Rectangle(40, 0, 20, 19);
-					int nbMessages = discussion.getUnreadMessages();
-					if (nbMessages > 0 && (chatWindow == null || !chatWindow.isVisible())) {
-						int startPixel = 0;
-						if (nbMessages >= 10) {
-							Image img = imageLoader.getImage("large_red_bubble");
-							chatAreaBounds.x = bounds.width - img.getBounds().width;
-							e.gc.drawImage(img, chatAreaBounds.x, -1);
-							startPixel = chatAreaBounds.x + 14;
-							imageLoader.releaseImage("large_red_bubble");
-						} else {
-							Image img = imageLoader.getImage("red_bubble");
-							chatAreaBounds.x = bounds.width - img.getBounds().width;
-							e.gc.drawImage(img, chatAreaBounds.x, 0);
-							startPixel = chatAreaBounds.x + 13;
-							imageLoader.releaseImage("red_bubble");
-						}
-
-						e.gc.setForeground(ColorCache.getColor(e.gc.getDevice(), 255, 255,
-								255));
-						Point textSize = e.gc.stringExtent("" + nbMessages);
-						e.gc.drawText("" + nbMessages, startPixel - textSize.x / 2, 3, true);
-
-					} else {
-						Image img = imageLoader.getImage("grey_bubble");
-						chatAreaBounds.x = bounds.width - img.getBounds().width;
-						e.gc.drawImage(img, chatAreaBounds.x, 0);
-						imageLoader.releaseImage("grey_bubble");
-					}
-				} else {
-					chatAreaBounds = null;
-				}
-
-				boolean showShareIcon = !viewer.isEditMode();
-
-				if ( showShareIcon && chatAreaBounds == null && vuzeBuddy.canSubscribeToCategory()){
-					subsAreaBounds = new Rectangle(0, 0, 18, 8);
-					Set<String> possible = vuzeBuddy.getSubscribableCategories();
-					int hits = 0;
-					for ( String x: possible ){
-						if ( vuzeBuddy.isSubscribedToCategory( x )){
-							hits++;
-						}
-					}
-					String key;
-					
-					if ( hits == 0 ){
-						
-						key = "rss_buddy_orange";
-					}else if ( hits < possible.size()){
-						key = "rss_buddy_gray";
-					}else{
-						key = "rss_buddy_green";
-					}
-					Image img = imageLoader.getImage( key );
-					subsAreaBounds.x = bounds.width - img.getBounds().width - 10;
-					subsAreaBounds.y = 4;
-					e.gc.drawImage(img, subsAreaBounds.x, subsAreaBounds.y);
-					imageLoader.releaseImage( key );
-				}else{
-					subsAreaBounds = null;
-				}
-			}
-		});
-
-//		canvas.addMouseTrackListener(new MouseTrackListener() {
-//
-//			public void mouseHover(MouseEvent e) {
-//
-//			}
-//
-//			public void mouseExit(MouseEvent e) {
-//				if (false == isFullyVisible()) {
-//					return;
-//				}
-//				isActivated = false;
-//				canvas.redraw();
-//			}
-//
-//			public void mouseEnter(MouseEvent e) {
-//				if (false == isFullyVisible()) {
-//					return;
-//				}
-//				if (false == isActivated) {
-//					//isActivated = true;
-//					canvas.redraw();
-//				}
-//			}
-//		});
-
-		canvas.addMouseListener(new MouseListener() {
-
-			public void mouseUp(MouseEvent e) {
-				if (false == isFullyVisible()) {
-					return;
-				}
-				if (e.button != 1) {
-					return;
-				}
-
-				/*
-				 * If it's in Share mode then clicking on any part will add it to Share
-				 */
-				if (true == viewer.isShareMode()) {
-					doAddBuddyToShare();
-					return;
-				}
-
-				if (true == nameAreaBounds.contains(e.x, e.y)) {
-					doLinkClicked();
-				} else if (decorator_remove_friend.contains(e.x, e.y)) {
-					if (true == viewer.isEditMode()) {
-						doRemoveBuddy();
-					}
-				} else if (decorator_add_to_share.contains(e.x, e.y)) {
-					
-				}
-				//No more selection
-				/*
-				else {
-					if ((e.stateMask & SWT.MOD1) == SWT.MOD1) {
-						viewer.select(vuzeBuddy, !isSelected, true);
-					} else {
-						viewer.select(vuzeBuddy, !isSelected, false);
-					}
-					canvas.redraw();
-				}*/
-
-			}
-
-			public void mouseDown(MouseEvent e) {
-				//It's conflicting with double click otherwise ...
-				if (chatAreaBounds != null && chatAreaBounds.contains(e.x, e.y)) {
-					doChatClicked();
-				}
-			}
-
-			public void mouseDoubleClick(MouseEvent e) {
-				if (false == viewer.isShareMode() && false == viewer.isEditMode()) {
-					doChatClicked();
-					return;
-				}
-			}
-		});
-		
-		canvas.addMouseTrackListener(new MouseTrackListener() {
-
-			public void mouseHover(MouseEvent e) {
-
-			}
-
-			public void mouseExit(MouseEvent e) {
-				if (false == isFullyVisible()) {
-					return;
-				}
-				isActivated = false;
-				canvas.redraw();
-			}
-
-			public void mouseEnter(MouseEvent e) {
-				if (false == isFullyVisible()) {
-					return;
-				}
-				if (false == isActivated) {
-					isActivated = true;
-					canvas.redraw();
-				}
-			}
-		});
-
-		canvas.addMouseMoveListener(new MouseMoveListener() {
-			private boolean lastActiveState = false;
-
-			private String lastTooltipText = canvas.getToolTipText();
-
-			public void mouseMove(MouseEvent e) {
-				if (false == isFullyVisible()) {
-					return;
-				}
-				if ((e.stateMask & SWT.MOD1) == SWT.MOD1) {
-					return;
-				}
-
-				/*
-				 * Optimization employed to minimize how often the tooltip text is updated;
-				 * updating too frequently causes the tooltip to 'stick' to the cursor which
-				 * can be annoying
-				 */
-				String tooltipText = "";
-				
-				if (true == viewer.isShareMode()) {
-					if (false == isSharedAlready()) {
-						tooltipText = tooltip_add_to_share;
-					} else {
-						tooltipText = tooltip;
-					}
-				} else if ( subsAreaBounds != null && subsAreaBounds.contains(e.x, e.y )){
-					
-					tooltipText = MessageText.getString( "friend.mod.subs" );
-
-				} else if (decorator_remove_friend.contains(e.x, e.y)) {
-					if (true == viewer.isEditMode()) {
-						tooltipText = tooltip_remove_friend;
-					} else {
-						tooltipText = tooltip;
-					}					
-				}else{
-					tooltipText = tooltip;
-				}
-
-				if (false == tooltipText.equals(lastTooltipText)) {
-					canvas.setToolTipText(tooltipText);
-					lastTooltipText = tooltipText;
-				}
-
-				Cursor cursor = null;
-				
-				if (true == nameAreaBounds.contains(e.x, e.y)) {
-					if (false == lastActiveState) {
-						nameLinkActive = true;
-						canvas.redraw();
-						lastActiveState = true;
-					}
-				} else 
-				if (chatAreaBounds != null && chatAreaBounds.contains(e.x, e.y)) {
-					cursor = canvas.getDisplay().getSystemCursor(SWT.CURSOR_HAND);
-				} else {
-					if (true == lastActiveState) {
-						nameLinkActive = false;
-						canvas.redraw();
-						lastActiveState = false;
-					}
-				}
-				
-				if(nameLinkActive) {
-					cursor = canvas.getDisplay().getSystemCursor(SWT.CURSOR_HAND);
-				}
-				
-				canvas.setCursor(cursor);
-
-			}
-		});
-		
-//		canvas.addListener(SWT.Move, new Listener() {
-//			public void handleEvent(Event arg0) {
-//				if (chatWindow != null && chatWindow.isVisible()) {
-//					chatWindow.setPosition();
-//				}
-//			}
-//		});
-
-		initMenu();
-	}
-
-	public boolean isFullyVisible() {
-		return viewer.isFullyVisible(AvatarWidget.this);
-	}
-
-	private void initMenu() {
-		menu = new Menu(canvas);
-		canvas.setMenu(menu);
-
-		menu.addMenuListener(new MenuListener() {
-			boolean bShown = false;
-
-			public void menuHidden(MenuEvent e) {
-				bShown = false;
-
-				if (Constants.isOSX) {
-					return;
-				}
-
-				// Must dispose in an asyncExec, otherwise SWT.Selection doesn't
-				// get fired (async workaround provided by Eclipse Bug #87678)
-				e.widget.getDisplay().asyncExec(new AERunnable() {
-					public void runSupport() {
-						if (bShown || menu.isDisposed()) {
-							return;
-						}
-						MenuItem[] items = menu.getItems();
-						for (int i = 0; i < items.length; i++) {
-							items[i].dispose();
-						}
-					}
-				});
-			}
-
-			public void menuShown(MenuEvent e) {
-				MenuItem[] items = menu.getItems();
-				for (int i = 0; i < items.length; i++) {
-					items[i].dispose();
-				}
-
-				bShown = true;
-
-				fillMenu(menu);
-			}
-		});
-	}
-
-	protected void fillMenu(Menu menu) {
-		MenuItem item;
-
-		item = new MenuItem(menu, SWT.PUSH);
-		item.setEnabled(false);
-		item.setText(vuzeBuddy.getDisplayName());
-		item = new MenuItem(menu, SWT.SEPARATOR);
-		
-		item = new MenuItem(menu, SWT.PUSH);
-		Messages.setLanguageText(item, "v3.buddy.menu.viewprofile");
-		item.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				AvatarWidget aw = (AvatarWidget) canvas.getData("AvatarWidget");
-				if (aw != null) {
-					aw.doLinkClicked();
-				}
-			}
-		});
-
-		item = new MenuItem(menu, SWT.PUSH);
-		Messages.setLanguageText(item, "v3.buddy.menu.chat");
-		item.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				AvatarWidget aw = (AvatarWidget) canvas.getData("AvatarWidget");
-				if (aw != null) {
-					aw.doChatClicked();
-				}
-			}
-		});
-
-			// subs
-		
-		Menu subs_menu = new Menu(menu.getShell(), SWT.DROP_DOWN);
-		MenuItem subs_item = new MenuItem(menu, SWT.CASCADE);
-		Messages.setLanguageText(subs_item, "ConfigView.section.Subscriptions" );
-		subs_item.setMenu(subs_menu);
-
-		final Menu subs_out_menu = new Menu(subs_menu.getShell(), SWT.DROP_DOWN);
-		MenuItem subs_out_item = new MenuItem(subs_menu, SWT.CASCADE);
-		Messages.setLanguageText(subs_out_item, "v3.buddy.set.catout" );
-		subs_out_item.setMenu(subs_out_menu);
-
-		final Menu subs_in_menu = new Menu(subs_menu.getShell(), SWT.DROP_DOWN);
-		MenuItem subs_in_item = new MenuItem(subs_menu, SWT.CASCADE);
-		Messages.setLanguageText(subs_in_item, "v3.buddy.set.catin" );
-		subs_in_item.setMenu(subs_in_menu);
-
-		subs_menu.addMenuListener(
-			new MenuListener()
-			{
-				public void 
-				menuShown(
-					MenuEvent arg0 ) 
-				{
-					MenuItem[] items = subs_out_menu.getItems();
-					
-					for (int i = 0; i < items.length; i++){
-						items[i].dispose();
-					}
-					
-					items = subs_in_menu.getItems();
-					
-					for (int i = 0; i < items.length; i++){
-						items[i].dispose();
-					}
-					
-					AvatarWidget aw = (AvatarWidget) canvas.getData("AvatarWidget");
-				
-					if ( aw == null ){
-						
-						return;
-					}
-					
-					Category[] cats = CategoryManager.getCategories();
-					
-					Arrays.sort(
-						cats,
-						new Comparator<Category>()
-						{
-							public int 
-							compare(
-								Category o1, 
-								Category o2 )
-							{
-								return( o1.getName().compareTo(o2.getName()));
-							}
-						});
-					
-					final VuzeBuddy vb = aw.getVuzeBuddy();
-
-					for ( Category c: cats ){
-						
-						int type = c.getType();
-						
-						if ( type == Category.TYPE_UNCATEGORIZED ){
-							
-							continue;
-						}
-						
-						final MenuItem item = new MenuItem(subs_out_menu, SWT.CHECK );
-						
-						final String cname;
-						
-						if ( type == Category.TYPE_ALL ){
-							
-							cname = "All";
-							
-						}else{
-							
-							cname = c.getName();
-						}
-						
-						item.setText( cname);
-						
-						boolean is_selected = vb.isPublishedCategory( cname ); 
-						
-						item.setSelection( is_selected );
-						
-						if ( vb.canSetPublishedCategory( cname )){
-							
-							item.addListener(
-								SWT.Selection, 
-								new Listener() 
-								{
-									public void 
-									handleEvent(
-										Event event) 
-									{
-										vb.setPublishedCategory( cname, item.getSelection());
-									}
-								});
-						}else{
-							
-							item.setEnabled( false );
-						}
-					}
-										
-					String[] subscribable = vb.getSubscribableCategories().toArray( new String[0]);
-					
-					Arrays.sort(
-						subscribable,
-						new Comparator<String>()
-						{
-							public int 
-							compare(
-								String o1, 
-								String o2 )
-							{
-								return( o1.compareTo(o2));
-							}
-						});
-					
-					for ( final String cat: subscribable ){
-						
-						final MenuItem item = new MenuItem(subs_in_menu, SWT.CHECK );
-						
-						item.setText( cat );
-							
-						boolean is_selected = vb.isSubscribedToCategory( cat ); 
-						
-						item.setSelection( is_selected );
-
-						item.addListener(
-							SWT.Selection, 
-							new Listener() 
-							{
-								public void 
-								handleEvent(
-									Event event) 
-								{
-									vb.setSubscribedToCategory( cat, item.getSelection());
-								}
-							});
-					}
-				}
-					
-				public void 
-				menuHidden(
-					MenuEvent arg0 )
-				{
-				}
-			});
-		
-		if (Constants.isCVSVersion()) {
-			MenuItem itemMenuDebug = new MenuItem(menu, SWT.CASCADE);
-			itemMenuDebug.setText("Debug");
-			Menu menuCVS = new Menu(menu);
-			itemMenuDebug.setMenu(menuCVS);
-
-			item = new MenuItem(menuCVS, SWT.PUSH);
-			Messages.setLanguageText(item, "v3.buddy.menu.remove");
-			item.addSelectionListener(new SelectionAdapter() {
-				public void widgetSelected(SelectionEvent e) {
-					AvatarWidget aw = (AvatarWidget) canvas.getData("AvatarWidget");
-					if (aw != null) {
-						doRemoveBuddy();
-					}
-				}
-			});
-
-			item = new MenuItem(menuCVS, SWT.PUSH);
-			item.setText("Send Activity Message");
-			item.addSelectionListener(new SelectionAdapter() {
-				public void widgetSelected(SelectionEvent e) {
-					if (!LoginInfoManager.getInstance().isLoggedIn()) {
-						Utils.openMessageBox(null, SWT.ICON_ERROR, "No",
-								"not logged in. no can do");
-						return;
-					}
-					
-					SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow();
-					entryWindow.setTitle("Moo");
-					entryWindow.setMessage("Message:");
-					entryWindow.prompt();
-					if (!entryWindow.hasSubmittedInput()) {
-						return;
-					}
-					String txt = entryWindow.getSubmittedInput();
-
-					if (txt != null) {
-						txt = LoginInfoManager.getInstance().getUserInfo().userName
-								+ " says: \n" + txt;
-						VuzeActivitiesEntry entry = new VuzeActivitiesEntry(
-								SystemTime.getCurrentTime(), txt, "Test");
-						System.out.println("sending to " + vuzeBuddy.getDisplayName());
-						try {
-							vuzeBuddy.sendActivity(entry);
-						} catch (NotLoggedInException e1) {
-							Debug.out("Shouldn't Happen", e1);
-						}
-					}
-				}
-			});
-
-			item = new MenuItem(menuCVS, SWT.PUSH);
-			item.setText("Sync this buddy (via PK)");
-			item.addSelectionListener(new SelectionAdapter() {
-				public void widgetSelected(SelectionEvent e) {
-					if (!LoginInfoManager.getInstance().isLoggedIn()) {
-						Utils.openMessageBox(null, SWT.ICON_ERROR, "No",
-								"not logged in. no can do");
-						return;
-					}
-					final String pk = vuzeBuddy.getPublicKeys()[0];
-					final long lastUpdate = vuzeBuddy.getLastUpdated();
-					try {
-						PlatformBuddyMessenger.sync(new String[] {
-							pk
-						}, new VuzeBuddySyncListener() {
-							public void syncComplete() {
-								Utils.execSWTThread(new AERunnable() {
-									public void runSupport() {
-										if (vuzeBuddy.getLastUpdated() != lastUpdate) {
-											Utils.openMessageBox(Utils.findAnyShell(), SWT.OK, "Yay",
-													"Updated");
-										} else {
-											Utils.openMessageBox(Utils.findAnyShell(), SWT.OK, "Boo",
-													"Not Updated");
-										}
-									}
-								});
-							}
-						});
-					} catch (NotLoggedInException e1) {
-					}
-				}
-			});
-		}
-		
-		item = new MenuItem(menu, SWT.SEPARATOR);
-		
-		item = new MenuItem(menu, SWT.PUSH);
-		Messages.setLanguageText(item, "Subscription.menu.properties");
-		item.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				AvatarWidget aw = (AvatarWidget) canvas.getData("AvatarWidget");
-				if (aw != null) {
-					aw.doProperties();
-				}
-			}
-		});
-	}
-
-	private void doRemoveBuddy() {
-
-		//LightBoxShell lbShell = new LightBoxShell(parent.getShell(), false);
-
-		MessageBoxShell mBox = new MessageBoxShell(parent.getShell(),
-				MessageText.getString("v3.buddies.remove.buddy.dialog.title"),
-				MessageText.getString("v3.buddies.remove.buddy.dialog.text",
-						new String[] {
-							vuzeBuddy.getLoginID()
-						}), new String[] {
-					MessageText.getString("Button.remove"),
-					MessageText.getString("Button.cancel")
-				}, 1);
-
-		mBox.setLeftImage(SWT.ICON_QUESTION);
-
-
-		//Testing for == 1 is not good, because closing the shell actually returns -1
-		//which is != 1, and therefore it proceeds with the removal of the buddy.
-		if (0 != mBox.open()) {
-			return;
-		}
-		try {
-			VuzeBuddyManager.removeBuddy(vuzeBuddy, true);
-		} catch (NotLoggedInException e) {
-			// should not happen, unless the user cancelled
-			Debug.out(e);
-		}
-	}
-
-	private void doAddBuddyToShare() {
-		if (false == isSharedAlready()) {
-			viewer.addToShare(this);
-			sharedAlready = true;
-		} else {
-			viewer.removeFromShare(vuzeBuddy);
-			sharedAlready = false;
-		}
-		canvas.redraw();
-		canvas.update();
-	}
-
-	public void doHover() {
-
-	}
-
-	public void doClick() {
-
-	}
-
-	public void doMouseEnter() {
-
-	}
-
-	public void doDoubleClick() {
-
-	}
-
-	public void doLinkClicked() {
-
-		/*
-		 * Open the user profile page but only if NOT in Share or Add mode
-		 */
-		if (false == viewer.isShareMode() && false == viewer.isAddBuddyMode()) {
-			UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-			if (null != uiFunctions) {
-				String url = getVuzeBuddy().getProfileUrl("buddy-bar");
-				uiFunctions.viewURL(url, SkinConstants.VIEWID_BROWSER_BROWSE, "buddy-bar");
-			}
-		}
-	}
-
-	public void setChatDiscussion(ChatDiscussion discussion) {
-		if (this.discussion != discussion) {
-			this.discussion = discussion;
-		}
-		if (discussion.getUnreadMessages() > 0) {
-			if (canvas != null && !canvas.isDisposed()) {
-				canvas.getDisplay().asyncExec(new Runnable() {
-					public void run() {
-						if (!canvas.isDisposed()) {
-							canvas.redraw();
-						}
-					}
-				});
-			}
-		}
-	}
-
-	public boolean isChatWindowVisible() {
-		return chatWindow != null && chatWindow.isVisible();
-	}
-
-	public void doChatClicked() {
-		doChatClicked(false);
-	}
-
-	public void doChatClicked(final boolean noHide) {
-		if (false == viewer.isShareMode() && false == viewer.isAddBuddyMode()) {
-			if (chatWindow == null || chatWindow.isDisposed()) {
-				if (discussion == null) {
-					discussion = viewer.getChat().getChatDiscussionFor(vuzeBuddy);
-				}
-				Display display = canvas.getDisplay();
-				display.asyncExec(new Runnable() {
-					public void run() {
-						chatWindow = new ChatWindow(AvatarWidget.this, viewer.getChat(),
-								discussion);
-					}
-				});
-
-			} else {
-				if (chatWindow.isVisible() && !noHide) {
-					chatWindow.hide();
-				} else {
-					chatWindow.show();
-				}
-			}
-
-			canvas.redraw();
-		}
-	}
-
-	public void
-	doProperties()
-	{
-		SimpleDateFormat df = new SimpleDateFormat();
-
-		String[] keys = {
-				"v3.buddy.prop.dn",
-				"v3.buddy.prop.un",
-				"v3.buddy.prop.on",
-				"v3.buddy.prop.lupd",
-				"v3.buddy.prop.pks",
-				"v3.buddy.prop.pc",
-				"v3.buddy.prop.catout",
-				"v3.buddy.prop.catin",
-			};
-		
-		String[] values = { 
-				vuzeBuddy.getDisplayName(),
-				vuzeBuddy.getLoginID(),
-				MessageText.getString( vuzeBuddy.isOnline( true )?"GeneralView.yes":"GeneralView.no" ),
-				df.format( new Date( vuzeBuddy.getLastUpdated())),
-				String.valueOf( vuzeBuddy.getPublicKeys().length ),
-				String.valueOf(vuzeBuddy.getStoredChatMessageCount()),
-				getString( vuzeBuddy.getPublishedCategories()),
-				getString( vuzeBuddy.getSubscribableCategories()),
-			};
-		
-		new PropertiesWindow( vuzeBuddy.getDisplayName(), keys, values );
-	}
-	
-	protected String
-	getString(
-		Set<String>		cats )
-	{
-		if ( cats == null || cats.size() == 0 ){
-			
-			return( "" );
-			
-		}else{
-			
-			String	str = "";
-			
-			cats = new TreeSet<String>( cats );
-			
-			Iterator<String> it = cats.iterator();
-			
-			while( it.hasNext()){
-				
-				str += (str.length()==0?"":", ") + it.next();
-			}
-			
-			return( str );
-		}
-	}
-	
-	public Control getControl() {
-		return canvas;
-	}
-
-	public int getBorderWidth() {
-		return highlightBorder;
-	}
-
-	public void setBorderWidth(int borderWidth) {
-		//		this.highlightBorder = borderWidth;
-	}
-
-	public VuzeBuddySWT getVuzeBuddy() {
-		return vuzeBuddy;
-	}
-
-	public boolean isSelected() {
-		return isSelected;
-	}
-
-	public void setSelected(boolean isSelected) {
-		this.isSelected = isSelected;
-	}
-
-	public void refreshVisual() {
-		tooltip = vuzeBuddy.getDisplayName() + " (" + vuzeBuddy.getLoginID() + ")";
-
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				if (null != canvas && false == canvas.isDisposed()) {
-					canvas.redraw();
-				}
-			}
-		});
-
-	}
-
-	public Color getTextColor() {
-		return textColor;
-	}
-
-	public void setTextColor(Color textColor) {
-		this.textColor = textColor;
-	}
-	
-	public Color getSelectedTextColor() {
-		return selectedTextColor;
-	}
-
-	public void setSelectedTextColor(Color selectedTextColor) {
-		this.selectedTextColor = selectedTextColor;
-	}
-
-	public Color getTextLinkColor() {
-		return textLinkColor;
-	}
-
-	public void setTextLinkColor(Color textLinkColor) {
-		this.textLinkColor = textLinkColor;
-	}
-
-	public void dispose(boolean animate, boolean relayout, final AfterDisposeListener listener) {
-		if (null != canvas && false == canvas.isDisposed()) {
-			if (chatWindow != null && !chatWindow.isDisposed()) {
-				chatWindow.close();
-			}
-			ImageLoader imageLoader = ImageLoader.getInstance();
-			imageLoader.releaseImage("image.buddy.remove");
-			imageLoader.releaseImage("image.buddy.add.to.share");
-			imageLoader.releaseImage("image.buddy.remove-over");
-			imageLoader.releaseImage("image.buddy.add.to.share-selected");
-
-			if (true == animate) {
-				Utils.execSWTThreadLater(0, new AERunnable() {
-					public void runSupport() {
-
-						isDisposing = true;
-
-						/*
-						 * KN: TODO: disposal check is still not complete since it could still happen
-						 * between the .isDisposed() check and the .redraw() or .update() calls.
-						 */
-						while (alpha > 20 && false == canvas.isDisposed()) {
-							alpha -= 30;
-							canvas.redraw();
-							canvas.update();
-
-							try {
-								Thread.sleep(50);
-							} catch (InterruptedException e) {
-								e.printStackTrace();
-							}
-						}
-
-						if (false == canvas.isDisposed()) {
-							canvas.dispose();
-							parent.layout(true);
-							if (null != listener) {
-								listener.disposed();
-							}
-						}
-					}
-				});
-			} else {
-				if (false == canvas.isDisposed()) {
-					canvas.dispose();
-					if (relayout) {
-						parent.layout(true);
-					}
-					if (null != listener) {
-						listener.disposed();
-					}
-				}
-			}
-
-		}
-	}
-
-	public boolean isSharedAlready() {
-		return sharedAlready;
-	}
-
-	public void setSharedAlready(boolean sharedAlready) {
-		this.sharedAlready = sharedAlready;
-		refreshVisual();
-	}
-
-	public void setVuzeBuddy(VuzeBuddySWT vuzeBuddy) {
-		if (null != vuzeBuddy) {
-			this.vuzeBuddy = vuzeBuddy;
-			refreshVisual();
-		}
-	}
-
-	public Point getAvatarImageSize() {
-		return imageSize;
-	}
-
-	public void setAvatarImageSize(Point avatarImageSize) {
-		this.imageSize = avatarImageSize;
-	}
-
-	public Point getAvatarNameSize() {
-		return nameAreaSize;
-	}
-
-	public void setAvatarNameSize(Point avatarNameSize) {
-		this.nameAreaSize = avatarNameSize;
-	}
-
-	public Color getImageBorderColor() {
-		return imageBorderColor;
-	}
-
-	public void setImageBorderColor(Color imageBorderColor) {
-		this.imageBorderColor = imageBorderColor;
-	}
-
-	public int getAvatarImageBorder() {
-		return imageBorder;
-	}
-
-	public void setAvatarImageBorder(int avatarImageBorder) {
-		this.imageBorder = avatarImageBorder;
-	}
-
-	public int getImageBorder() {
-		return imageBorder;
-	}
-
-	public void setImageBorder(int imageBorder) {
-		this.imageBorder = imageBorder;
-	}
-
-	public Color getSelectedColor() {
-		return selectedColor;
-	}
-
-	public void setSelectedColor(Color selectedColor) {
-		this.selectedColor = selectedColor;
-	}
-
-	public Color getHighlightedColor() {
-		return highlightedColor;
-	}
-
-	public void setHighlightedColor(Color highlightedColor) {
-		this.highlightedColor = highlightedColor;
-	}
-
-	public boolean isEnabled() {
-		if (false == isEnabled) {
-			return isEnabled;
-		}
-
-		return viewer.isEnabled();
-	}
-
-	public void setEnabled(boolean isEnabled) {
-		this.isEnabled = isEnabled;
-	}
-
-	private int getAlpha() {
-		if (!isDisposing) {
-			if (true == isEnabled()) {
-				alpha = 255;
-			} else {
-				alpha = 128;
-			}
-		}
-
-		return alpha;
-	}
-
-	public interface AfterDisposeListener
-	{
-		public void disposed();
-	}
-	
-	public void setSharePage(SharePage sharePage) {
-		this.sharePage = sharePage;
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/Browse.java b/com/aelitis/azureus/ui/swt/views/skin/Browse.java
index 3800c64..1e3dc9b 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/Browse.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/Browse.java
@@ -33,6 +33,8 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.UIInputReceiver;
+import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
 import org.gudy.azureus2.plugins.ui.UIManager;
 import org.gudy.azureus2.plugins.ui.menus.MenuItem;
 import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
@@ -218,10 +220,13 @@ public class Browse
 			menuItem.addListener(new MenuItemListener() {
 				public void selected(MenuItem menu, Object target) {
 					SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow("", "!URL!");
-					entryWindow.prompt();
-					if (entryWindow.hasSubmittedInput()) {
-						browserSkinObject.setURL(entryWindow.getSubmittedInput());
-					}
+					entryWindow.prompt(new UIInputReceiverListener() {
+						public void UIInputReceiverClosed(UIInputReceiver entryWindow) {
+							if (entryWindow.hasSubmittedInput()) {
+								browserSkinObject.setURL(entryWindow.getSubmittedInput());
+							}
+						}
+					});
 				}
 			});
 
@@ -292,14 +297,19 @@ public class Browse
 				if (shell == null) {
 					return;
 				}
-				final Browser browser = new Browser(shell,
-						Utils.getInitialBrowserStyle(SWT.NONE));
+				final Browser browser = Utils.createSafeBrowser(shell, SWT.NONE);
+				if (browser == null) {
+					return;
+				}
 				browser.setVisible(false);
 
 				browser.addProgressListener(new ProgressListener() {
 					public void completed(ProgressEvent event) {
 						Utils.execSWTThreadLater(1000, new AERunnable() {
 							public void runSupport() {
+								if (browser.isDisposed() || browser.getShell().isDisposed()) {
+									return;
+								}
 								browser.setUrl("about:blank");
 								browser.dispose();
 							}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/BuddiesViewer.java b/com/aelitis/azureus/ui/swt/views/skin/BuddiesViewer.java
deleted file mode 100644
index 832028f..0000000
--- a/com/aelitis/azureus/ui/swt/views/skin/BuddiesViewer.java
+++ /dev/null
@@ -1,991 +0,0 @@
-package com.aelitis.azureus.ui.swt.views.skin;
-
-import java.util.*;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.DelayedEvent;
-import org.gudy.azureus2.platform.PlatformManager;
-import org.gudy.azureus2.plugins.ui.config.BooleanParameter;
-import org.gudy.azureus2.ui.common.util.UserAlerts;
-import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
-import org.gudy.azureus2.ui.swt.Utils;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.VuzeBuddyListener;
-import com.aelitis.azureus.buddy.chat.*;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPlugin;
-import com.aelitis.azureus.ui.skin.SkinConstants;
-import com.aelitis.azureus.ui.swt.buddy.VuzeBuddySWT;
-import com.aelitis.azureus.ui.swt.buddy.chat.impl.MessageNotificationWindow;
-import com.aelitis.azureus.ui.swt.layout.SimpleReorderableListLayout;
-import com.aelitis.azureus.ui.swt.layout.SimpleReorderableListLayoutData;
-import com.aelitis.azureus.ui.swt.shells.friends.SharePage;
-import com.aelitis.azureus.ui.swt.skin.*;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
-import com.aelitis.azureus.util.ConstantsVuze;
-import com.aelitis.azureus.util.FAQTopics;
-
-public class BuddiesViewer
-	extends SkinView
-{
-
-	private static final boolean SHOW_ONLINE_STATUS = System.getProperty(
-			"az.buddy.show_online", "1").equals("1");
-
-	public static final int none_active_mode = 0;
-
-	public static final int edit_mode = 1;
-
-	public static final int share_mode = 2;
-
-	public static final int invite_mode = 3;
-
-	public static final int add_buddy_mode = 4;
-
-	public static final int disabled_mode = 5;
-
-	private Composite avatarsPanel = null;
-
-	private Composite parent = null;
-
-	private SWTSkin skin = null;
-
-	private int avatarHightLightBorder;
-
-	private int avatarImageBorder;
-
-	private Point avatarImageSize = null;
-
-	private Point avatarNameSize = null;
-
-	private Point avatarSize = null;
-
-	private int hSpacing;
-
-	private List avatarWidgets = new ArrayList();
-
-	private boolean isShareMode = false;
-
-	private boolean isEditMode = false;
-
-	private boolean isAddBuddyMode = false;
-
-	private boolean isEnabled = true;
-
-	private Color textColor = null;
-	
-	private Color selectedTextColor = null;
-
-	private Color textLinkColor = null;
-
-	private Color imageBorderColor = null;
-
-	private Color selectedColor = null;
-
-	private Color highlightedColor = null;
-
-	private SWTSkinObject soNoBuddies;
-
-	private com.aelitis.azureus.ui.swt.shells.friends.SharePage sharePage;
-
-	private List buddiesList;
-
-	private boolean reorder_outstanding;
-
-	private Chat chat;
-
-	private Color colorFileDragBorder;
-
-	private Color colorFileDragBG;
-
-	private ScrolledComposite scrollable;
-
-	private AERunnable runnableSetPanelSize;
-	private boolean runnableSetPanelSizeQueued = false;
-	
-	private String filter;
-
-	private boolean bRegexSearch = false;
-
-	public BuddiesViewer() {
-
-		runnableSetPanelSize = new AERunnable() {
-			public void runSupport() {
-				runnableSetPanelSizeQueued = false;
-				avatarsPanel.layout();
-				fixupScrollableHeight();
-			}
-		};
-
-
-		chat = new Chat();
-		chat.addChatListener(new ChatListener() {
-			public void newMessage(final VuzeBuddy from, final ChatMessage message) {
-				final AvatarWidget avatarWidget = findWidget(from);
-				if (avatarWidget != null) {
-					avatarWidget.setChatDiscussion(chat.getChatDiscussionFor(from));
-					BuddyPlugin plugin = VuzeBuddyManager.getBuddyPlugin();
-					if (plugin != null) {
-						BooleanParameter enabledNotifictions = plugin.getEnableChatNotificationsParameter();
-
-						if (!message.isMe() && enabledNotifictions.getValue()) {
-							avatarWidget.getControl().getDisplay().asyncExec(new Runnable() {
-								public void run() {
-									boolean isVisible = true;
-									if (avatarsPanel != null) {
-										if (!avatarsPanel.isVisible()) {
-											isVisible = false;
-										}
-										/*Shell mainShell = avatarsPanel.getShell();
-										boolean mVisible = mainShell.isVisible();
-										boolean mEnabled = mainShell.isEnabled();
-										boolean mGetEnabled = mainShell.getEnabled();
-										boolean isFC = mainShell.isFocusControl();
-										Shell activeShell = mainShell.getDisplay().getActiveShell();*/
-										if (avatarsPanel.getShell().getDisplay().getActiveShell() == null) {
-											isVisible = false;
-										}
-									}
-									//boolean isVisible = BuddiesViewer.this.isEnabled();
-									//avatarWidget.isChatWindowVisible();
-									if (!isVisible) {
-
-										new MessageNotificationWindow(avatarWidget, message);
-
-										/*
-										 * KN: MessageNotificationWindow above should really be moved into requestUserAttention()
-										 * so it can be handled in a platform-specific way if need be
-										 */
-										UserAlerts.requestUserAttention(
-												PlatformManager.USER_REQUEST_INFO, null);
-									}
-
-								}
-							});
-
-						}
-					}
-				}
-			}
-
-			public void updatedChat(VuzeBuddy buddy) {
-				final AvatarWidget avatarWidget = findWidget(buddy);
-				if (avatarWidget != null) {
-					avatarWidget.setChatDiscussion(chat.getChatDiscussionFor(buddy));
-				}
-			}
-		});
-
-		/*
-		 * backed this change out as the desired behaviour is to continue showing
-		 * buddies when logged out as all attempts to do something with buddy will
-		 * prompt for login
-		 * 
-		LoginInfoManager.getInstance().addListener(
-			new ILoginInfoListener()
-			{
-				public void 
-				loginUpdate(
-					LoginInfo 	info, 
-					boolean 	isNewLoginID )
-				{
-					Utils.execSWTThreadLater(0, new AERunnable() {
-						public void 
-						runSupport() 
-						{
-							boolean logged_in = LoginInfoManager.getInstance().isLoggedIn();
-						
-							boolean show_no_buddies = avatarWidgets.size() < 1 || !logged_in;
-								
-							showNoBuddiesPanel( show_no_buddies );
-						}
-					});
-				}
-			});
-			*/
-	}
-
-	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
-		skin = skinObject.getSkin();
-
-		SWTSkinProperties properties = skin.getSkinProperties();
-		colorFileDragBorder = properties.getColor("color.buddy.filedrag.bg.border");
-		colorFileDragBG = properties.getColor("color.buddy.filedrag.bg");
-
-		soNoBuddies = skin.getSkinObject("buddies-viewer-nobuddies-panel");
-
-		SWTSkinObject viewer = skin.getSkinObject(SkinConstants.VIEWID_BUDDIES_VIEWER);
-
-		if (null != viewer) {
-
-			parent = (Composite) skinObject.getControl();
-			parent.setBackgroundMode(SWT.INHERIT_FORCE);
-			scrollable = new ScrolledComposite(parent, SWT.V_SCROLL);
-			scrollable.setExpandHorizontal(true);
-			scrollable.setExpandVertical(true);
-			scrollable.setBackgroundMode(SWT.INHERIT_FORCE);
-			scrollable.getVerticalBar().setIncrement(10);
-			scrollable.getVerticalBar().setPageIncrement(65);
-
-			FormData fd = new FormData();
-			fd.top = new FormAttachment(0, 0);
-			fd.bottom = new FormAttachment(100, 0);
-			fd.left = new FormAttachment(0, 0);
-			fd.right = new FormAttachment(100, 0);
-			scrollable.setLayoutData(fd);
-
-			avatarsPanel = new Composite(scrollable, SWT.NONE);
-			avatarsPanel.setBackgroundMode(SWT.INHERIT_FORCE);
-			scrollable.setContent(avatarsPanel);
-
-			scrollable.addListener(SWT.Resize, new Listener() {
-				public void handleEvent(Event event) {
-					fixupScrollableHeight();
-				}
-			});
-
-			/*
-			 * Specify avatar dimensions and attributes before creating the avatars
-			 */
-			textColor =  parent.getDisplay().getSystemColor(
-					SWT.COLOR_LIST_FOREGROUND);
-			selectedTextColor =  parent.getDisplay().getSystemColor(
-					SWT.COLOR_LIST_SELECTION_TEXT);
-			textLinkColor = properties.getColor("color.links.hover");
-			imageBorderColor = properties.getColor("color.buddy.bg.border");
-			selectedColor = parent.getDisplay().getSystemColor(
-					SWT.COLOR_LIST_SELECTION);
-			highlightedColor = parent.getDisplay().getSystemColor(
-					SWT.COLOR_WIDGET_DARK_SHADOW);
-
-			avatarHightLightBorder = 0;
-			avatarImageBorder = 1;
-			hSpacing = 1;
-			avatarImageSize = new Point(40, 40);
-			avatarNameSize = new Point(60, 30);
-			avatarSize = new Point(0, 0);
-			avatarSize.x = Math.max(avatarNameSize.x, avatarImageSize.x)
-					+ (2 * (avatarHightLightBorder + avatarImageBorder));
-			avatarSize.y = avatarNameSize.y + avatarImageSize.y
-					+ (2 * (avatarHightLightBorder + avatarImageBorder) + 6);
-
-			// fill buddies after the ui dust has settled.  Since fillBuddies
-			// adds a buddy listener, delaying this allows for the buddy list
-			// to the complete
-			AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
-				public void azureusCoreRunning(AzureusCore core) {
-					Utils.execSWTThreadLater(100, new AERunnable() {
-						public void runSupport() {
-							if (avatarsPanel == null || avatarsPanel.isDisposed()) {
-								return;
-							}
-							fillBuddies();
-							avatarsPanel.layout(true);
-						}
-					});
-				}
-			});
-
-			/* UNCOMMENT THIS SECTION TO REVERT TO A ROW LAYOUT*/
-//			RowLayout rLayout = new RowLayout(SWT.HORIZONTAL);
-//			rLayout.wrap = true;
-//			rLayout.spacing = hSpacing;
-//			avatarsPanel.setLayout(rLayout);
-
-			// COMMENT THIS SECTION TO REVERT TO A ROW LAYOUT
-			SimpleReorderableListLayout rLayout = new SimpleReorderableListLayout();
-			rLayout.margin = hSpacing;
-			rLayout.wrap = true;
-			rLayout.center = true;
-			avatarsPanel.setLayout(rLayout);
-
-			avatarsPanel.pack();
-
-			avatarsPanel.addMouseListener(new MouseAdapter() {
-				public void mouseDown(MouseEvent e) {
-					select(null, false, false);
-				}
-			});
-
-			avatarsPanel.addMouseListener(new MouseAdapter() {
-				public void mouseDown(MouseEvent e) {
-					select(null, false, false);
-				}
-			});
-
-			parent.layout();
-
-			hookFAQLink();
-			
-			hookImageAction();
-		}
-		
-		return null;
-
-	}
-
-	/**
-	 * 
-	 */
-	protected void fixupScrollableHeight() {
-		Rectangle r = scrollable.getClientArea();
-		scrollable.setMinHeight(avatarsPanel.computeSize(r.width, SWT.DEFAULT).y);
-	}
-
-	public boolean isEditMode() {
-		return isEditMode;
-	}
-
-	public void setEditMode(boolean value) {
-		if (isEditMode != value) {
-			isEditMode = value;
-			for (Iterator iterator = avatarWidgets.iterator(); iterator.hasNext();) {
-				AvatarWidget widget = (AvatarWidget) iterator.next();
-				widget.refreshVisual();
-			}
-
-			if (true == value) {
-				setShareMode(false,null);
-				setAddBuddyMode(false);
-			}
-		}
-	}
-
-	private void fillBuddies() {
-
-		List buddies = getBuddies();
-
-		showNoBuddiesPanel(buddies.size() == 0);
-
-		for (Iterator iterator = buddies.iterator(); iterator.hasNext();) {
-			VuzeBuddySWT vuzeBuddy = (VuzeBuddySWT) iterator.next();
-			createBuddyControls(avatarsPanel, vuzeBuddy);
-		}
-		avatarsPanel.layout();
-		fixupScrollableHeight();
-	}
-
-	private void showNoBuddiesPanel(boolean value) {
-		if (soNoBuddies != null && soNoBuddies.isVisible() != value) {
-			soNoBuddies.setVisible(value);
-		}
-	}
-
-	private AvatarWidget createBuddyControls(Composite composite,
-			final VuzeBuddySWT vuzeBuddy) {
-		
-		if (filter != null && filter.length() > 0) {
-  		String s = bRegexSearch ? filter : "\\Q"
-  				+ filter.replaceAll("[|;]", "\\\\E|\\\\Q") + "\\E";
-  		Pattern pattern = Pattern.compile(s, Pattern.CASE_INSENSITIVE);
-  
-  		if (!pattern.matcher(vuzeBuddy.getDisplayName()).find()
-  				&& !pattern.matcher(vuzeBuddy.getLoginID()).find()) {
-  			return null;
-  		}
-		}
-		
-		
-		AvatarWidget avatarWidget = new AvatarWidget(this, avatarSize,
-				avatarImageSize, avatarNameSize, vuzeBuddy);
-		avatarWidget.setBorderWidth(avatarHightLightBorder);
-		avatarWidget.setTextColor(textColor);
-		avatarWidget.setSelectedTextColor(selectedTextColor);
-		avatarWidget.setTextLinkColor(textLinkColor);
-		avatarWidget.setImageBorderColor(imageBorderColor);
-		avatarWidget.setImageBorder(avatarImageBorder);
-		avatarWidget.setSelectedColor(selectedColor);
-		avatarWidget.setHighlightedColor(highlightedColor);
-
-		/* UNCOMMENT THIS SECTION TO REVERT TO A ROW LAYOUT*/
-//		RowData rData = new RowData();
-//		rData.width = avatarSize.x;
-//		rData.height = avatarSize.y;
-//		avatarWidget.getControl().setLayoutData(rData);
-
-		// COMMENT THIS SECTION TO REVERT TO A ROW LAYOUT
-				SimpleReorderableListLayoutData rData = new SimpleReorderableListLayoutData();
-				rData.width = avatarSize.x;
-				rData.height = avatarSize.y;
-				rData.position = (int) VuzeBuddyManager.getBuddyPosition(vuzeBuddy);
-		avatarWidget.getControl().setLayoutData(rData);
-
-		avatarWidgets.add(avatarWidget);
-
-		chat.checkBuddy(vuzeBuddy);
-
-		return avatarWidget;
-	}
-	
-	public void openFilterDialog() {
-		SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
-				"MyTorrentsView.dialog.setFilter.title",
-				"MyTorrentsView.dialog.setFilter.text");
-		entryWindow.setPreenteredText(filter, false);
-		entryWindow.prompt();
-		if (!entryWindow.hasSubmittedInput()) {
-			return;
-		}
-		String message = entryWindow.getSubmittedInput();
-
-		if (message == null) {
-			message = "";
-		}
-		
-		filter = message;
-
-		for (Iterator iterator = avatarWidgets.iterator(); iterator.hasNext();) {
-			AvatarWidget widget = (AvatarWidget) iterator.next();
-			
-			widget.dispose(false, false, null);
-			iterator.remove();
-		}
-		
-		fillBuddies();
-	}
-	
-
-	/**
-	 * Returns whether the given <code>AvatarWidget</code> is fully visible in the view port of the viewer
-	 */
-	public boolean isFullyVisible(AvatarWidget avatarWidget) {
-		if (null != avatarWidget && null != avatarWidget.getControl()
-				&& false == avatarWidget.getControl().isDisposed()) {
-
-			Rectangle controlBounds = avatarWidget.getControl().getBounds();
-			if (controlBounds.x + controlBounds.width < avatarsPanel.getBounds().width
-					- avatarsPanel.getBounds().x) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	public void removeBuddy(final AvatarWidget widget) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				if (avatarsPanel == null || avatarsPanel.isDisposed()) {
-					return;
-				}
-				avatarWidgets.remove(widget);
-				widget.dispose(true, true, new AvatarWidget.AfterDisposeListener() {
-					public void disposed() {
-						avatarsPanel.setSize(avatarsPanel.computeSize(SWT.DEFAULT,
-								SWT.DEFAULT, true));
-						if (avatarWidgets.size() < 1) {
-							showNoBuddiesPanel(true);
-						}
-					}
-				});
-
-			}
-		});
-	}
-
-	public void removeBuddy(VuzeBuddy buddy) {
-		AvatarWidget widget = findWidget(buddy);
-		if (null != widget) {
-			removeBuddy(widget);
-		} else {
-			Debug.out("Unknown VuzeBuddy; can not remove from viewer since we don't have it.");
-		}
-	}
-
-	public void updateBuddy(final VuzeBuddy buddy) {
-		if (buddy instanceof VuzeBuddySWT) {
-
-			Utils.execSWTThreadLater(0, new AERunnable() {
-
-				public void runSupport() {
-					if (avatarsPanel == null || avatarsPanel.isDisposed()) {
-						return;
-					}
-					AvatarWidget widget = findWidget(buddy);
-					if (null != widget) {
-						widget.setVuzeBuddy((VuzeBuddySWT) buddy);
-					} else {
-						/*
-						 * If not found yet then we create the avatar for it; this really should not happen
-						 * but we'll handle it just in case
-						 */
-						addBuddy(buddy);
-					}
-				}
-			});
-
-		}
-	}
-
-	public void addBuddy(final VuzeBuddy buddy) {
-		if (buddy instanceof VuzeBuddySWT) {
-			Utils.execSWTThreadLater(0, new AERunnable() {
-				public void runSupport() {
-					if (avatarsPanel == null || avatarsPanel.isDisposed()) {
-						return;
-					}
-					AvatarWidget widget = findWidget(buddy);
-					if (widget == null) {
-						if (soNoBuddies != null) {
-							soNoBuddies.setVisible(false);
-						}
-						createBuddyControls(avatarsPanel, (VuzeBuddySWT) buddy);
-						
-						if (!runnableSetPanelSizeQueued) {
-							runnableSetPanelSizeQueued = true;
-							Utils.execSWTThreadLater(100, runnableSetPanelSize);
-						}
-					}
-				}
-			});
-			
-		} else {
-			Debug.out("Wrong type VuzeBuddy... must be of type VuzeBuddySWT");
-		}
-	}
-
-	private AvatarWidget findWidget(VuzeBuddy buddy) {
-		if (null != buddy) {
-			for (Iterator iterator = avatarWidgets.iterator(); iterator.hasNext();) {
-				AvatarWidget widget = (AvatarWidget) iterator.next();
-				if (null != widget.getVuzeBuddy()) {
-					if (true == buddy.getLoginID().equals(
-							widget.getVuzeBuddy().getLoginID())) {
-						return widget;
-					}
-				}
-			}
-		}
-
-		return null;
-	}
-
-	/**
-	 * Return a list of <code>VuzeBuddySWT</code> that are currently selected
-	 * @return
-	 */
-	public List getSelection() {
-		List selected = new ArrayList();
-		for (Iterator iterator = avatarWidgets.iterator(); iterator.hasNext();) {
-			AvatarWidget widget = (AvatarWidget) iterator.next();
-			if (true == widget.isSelected()) {
-				selected.add(widget.getVuzeBuddy());
-			}
-		}
-		return selected;
-	}
-
-	public void select(VuzeBuddySWT buddy, boolean value, boolean appendSelection) {
-
-		if (null != buddy) {
-			for (Iterator iterator = avatarWidgets.iterator(); iterator.hasNext();) {
-				AvatarWidget widget = (AvatarWidget) iterator.next();
-				if (true == buddy.equals(widget.getVuzeBuddy())) {
-					widget.setSelected(value);
-					if (true == appendSelection) {
-						break;
-					}
-				} else if (false == appendSelection) {
-					if (true == value) {
-						if (widget.isSelected() != false) {
-							widget.setSelected(false);
-							widget.refreshVisual();
-						}
-					} else {
-						widget.setSelected(false);
-						widget.refreshVisual();
-					}
-				}
-			}
-		}
-		/*
-		 * De-select all buddies if the given 'buddy' is null
-		 */
-		else {
-			for (Iterator iterator = avatarWidgets.iterator(); iterator.hasNext();) {
-				AvatarWidget widget = (AvatarWidget) iterator.next();
-				if (true == widget.isSelected()) {
-					widget.setSelected(false);
-					widget.refreshVisual();
-				}
-			}
-		}
-	}
-
-	private void recomputeOrder(boolean delay) {
-
-		if (delay) {
-
-			synchronized (this) {
-
-				if (reorder_outstanding) {
-
-					return;
-				}
-
-				reorder_outstanding = true;
-
-				new DelayedEvent("BuddiesViewer:delayReorder", 5 * 1000,
-						new AERunnable() {
-							public void runSupport() {
-								synchronized (BuddiesViewer.this) {
-
-									reorder_outstanding = false;
-								}
-
-								recomputeOrder(false);
-							}
-						});
-
-				return;
-			}
-		}
-
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-
-				/* UNCOMMENT THIS SECTION TO REVERT TO A ROW LAYOUT
-				return;
-				*/
-
-				// COMMENT THIS SECTION TO REVERT TO A ROW LAYOUT
-				if (avatarsPanel == null || avatarsPanel.isDisposed())
-					return;
-
-				final List buddies = VuzeBuddyManager.getAllVuzeBuddies();
-
-				//Only sort by online status if we show it
-				if (SHOW_ONLINE_STATUS) {
-					Collections.sort(buddies, new Comparator() {
-						public int compare(Object o1, Object o2) {
-							VuzeBuddy v1 = (VuzeBuddy) o1;
-							VuzeBuddy v2 = (VuzeBuddy) o2;
-							int score = 0;
-							ChatDiscussion d1 = getChat().getChatDiscussionFor(v1);
-							ChatDiscussion d2 = getChat().getChatDiscussionFor(v2);
-							if(d1 != null && d1.getUnreadMessages() > 0) {
-								score-= 1;
-							}
-							if(d2 != null && d2.getUnreadMessages() > 0) {
-								score +=1;
-							}
-							
-							if(score == 0) {
-								if(d1 != null && d1.getNbMessages() > 0) {
-									score-= 1;
-								}
-								if(d2 != null && d2.getNbMessages() > 0) {
-									score +=1;
-								}
-							}
-							
-							if(score == 0) {
-								score -= v1.isOnline(true) ? 1 : 0;
-								score += v2.isOnline(true) ? 1 : 0;
-							}
-							
-							return score;
-						}
-					});
-				}
-
-				boolean changed = false;
-				for (int i = 0; i < buddies.size(); i++) {
-					VuzeBuddy buddy = (VuzeBuddy) buddies.get(i);
-					AvatarWidget widget = findWidget(buddy);
-					if (widget != null) {
-						Control control = widget.getControl();
-						if (control != null && !control.isDisposed()) {
-							Object data = widget.getControl().getLayoutData();
-							if (data instanceof SimpleReorderableListLayoutData) {
-								SimpleReorderableListLayoutData rData = (SimpleReorderableListLayoutData) widget.getControl().getLayoutData();
-								if (rData.position != i) {
-									rData.position = i;
-									changed = true;
-								}
-							}
-						}
-					}
-				}
-				if (changed) {
-					avatarsPanel.layout();
-				}
-			}
-		});
-	}
-
-	private List getBuddies() {
-
-		/*
-		 * Add the listener only once at the beginning
-		 */
-		if (null == buddiesList) {
-			VuzeBuddyManager.addListener(new VuzeBuddyListener() {
-
-				public void buddyRemoved(VuzeBuddy buddy) {
-					removeBuddy(buddy);
-					recomputeOrder(false);
-				}
-
-				public void buddyChanged(VuzeBuddy buddy) {
-					updateBuddy(buddy);
-					recomputeOrder(true);
-				}
-
-				public void buddyAdded(VuzeBuddy buddy, int position) {
-					addBuddy(buddy);
-					recomputeOrder(false);
-				}
-
-				public void buddyOrderChanged() {
-
-				}
-			}, false);
-		}
-
-		buddiesList = VuzeBuddyManager.getAllVuzeBuddies();
-		return buddiesList;
-	}
-
-	public Composite getControl() {
-		return avatarsPanel;
-	}
-
-	public boolean isShareMode() {
-		return isShareMode;
-	}
-
-	public void addAllToShare() {
-		addToShare(avatarWidgets);
-	}
-
-	public void removeAllFromShare() {
-		removeFromShare(avatarWidgets);
-	}
-
-	public void addToShare(List avatars) {
-
-		for (Iterator iterator = avatars.iterator(); iterator.hasNext();) {
-			Object object = (Object) iterator.next();
-			if (object instanceof AvatarWidget) {
-				addToShare((AvatarWidget) object);
-			}
-		}
-	}
-
-	public void addToShare(AvatarWidget widget) {
-		/*if (null == sharePage) {
-			SkinView detailPanelView = SkinViewManager.getByClass(DetailPanel.class);
-			if (detailPanelView instanceof DetailPanel) {
-				DetailPanel detailPanel = ((DetailPanel) detailPanelView);
-				sharePage = (SharePage) detailPanel.getPage(SharePage.PAGE_ID);
-
-			} else {
-				throw new IllegalArgumentException(
-						"Oops.. looks like the DetailPanel skin is not properly initialized");
-			}
-		}*/
-		if(sharePage != null) {
-			sharePage.addBuddy(widget.getVuzeBuddy());
-		}
-		widget.setSharedAlready(true);
-	}
-
-	public void removeFromShare(List avatars) {
-
-		for (Iterator iterator = avatars.iterator(); iterator.hasNext();) {
-			Object object = (Object) iterator.next();
-			if (object instanceof AvatarWidget) {
-				removeFromShare((AvatarWidget) object);
-			}
-		}
-	}
-
-	public void removeFromShare(AvatarWidget widget) {
-		if(sharePage != null) {
-			sharePage.removeBuddy(widget.getVuzeBuddy());
-		}
-		widget.setSharedAlready(false);
-	}
-
-	public void addToShare(VuzeBuddy buddy) {
-		AvatarWidget widget = findWidget(buddy);
-		if (null != widget) {
-			if (false == widget.isSharedAlready()) {
-				addToShare(widget);
-			}
-		}
-	}
-
-	public void addSelectionToShare() {
-
-		for (Iterator iterator = avatarWidgets.iterator(); iterator.hasNext();) {
-			AvatarWidget widget = (AvatarWidget) iterator.next();
-			if (true == widget.isSelected()) {
-				addToShare(widget);
-			}
-		}
-	}
-
-	public void removeFromShare(VuzeBuddy buddy) {
-
-		if (null != buddy) {
-			for (Iterator iterator = avatarWidgets.iterator(); iterator.hasNext();) {
-				AvatarWidget widget = (AvatarWidget) iterator.next();
-				if (null != widget.getVuzeBuddy()) {
-					if (true == buddy.getLoginID().equals(
-							widget.getVuzeBuddy().getLoginID())) {
-						if(sharePage != null) {
-							sharePage.removeBuddy(widget.getVuzeBuddy());
-						}
-						widget.setSharedAlready(false);
-						break;
-					}
-				}
-			}
-		}
-
-	}
-
-	public void setShareMode(boolean isShareMode,SharePage sharePage) {
-
-		this.sharePage = sharePage;
-		
-		if (this.isShareMode != isShareMode) {
-			this.isShareMode = isShareMode;
-			for (Iterator iterator = avatarWidgets.iterator(); iterator.hasNext();) {
-				AvatarWidget widget = (AvatarWidget) iterator.next();
-				if (false == isShareMode) {
-					widget.setSharedAlready(false);
-					widget.setSelected(false);
-				}
-				widget.refreshVisual();
-			}
-
-			if (true == isShareMode) {
-				setEditMode(false);
-				setAddBuddyMode(false);
-			}
-		}
-
-	}
-
-	public boolean isNonActiveMode() {
-		return !isAddBuddyMode() && !isShareMode() && !isEditMode();
-	}
-
-	public boolean isAddBuddyMode() {
-		return isAddBuddyMode;
-	}
-
-	public void setAddBuddyMode(boolean isAddBuddyMode) {
-		this.isAddBuddyMode = isAddBuddyMode;
-		/*
-		 * Turn off share mode when we enter add buddy flow
-		 */
-		if (true == isAddBuddyMode) {
-			setShareMode(false,null);
-			setEditMode(false);
-		}
-	}
-
-	public void setMode(int mode) {
-		if (mode == none_active_mode) {
-			setShareMode(false,null);
-			setEditMode(false);
-			setAddBuddyMode(false);
-		} else if (mode == edit_mode) {
-			setEditMode(true);
-		} else if (mode == share_mode) {
-			setShareMode(true,sharePage);
-		} else if (mode == add_buddy_mode) {
-			setAddBuddyMode(true);
-		}
-
-		if (mode == disabled_mode) {
-			setEnabled(false);
-		} else {
-			setEnabled(true);
-		}
-	}
-
-	public void hookFAQLink() {
-		SWTSkinObject FAQObject = skin.getSkinObject("buddies-viewer-nobuddies-link");
-		if (null != FAQObject) {
-			SWTSkinButtonUtility FAQButton = new SWTSkinButtonUtility(FAQObject);
-			FAQButton.addSelectionListener(new ButtonListenerAdapter() {
-				public void pressed(SWTSkinButtonUtility buttonUtility, SWTSkinObject skinObject, int stateMask) {
-					String url = ConstantsVuze.getDefaultContentNetwork().getFAQTopicService( FAQTopics.FAQ_TOPIC_WHAT_ARE_FRIENDS );
-					Utils.launch(url);
-				}
-			});
-		}
-	}
-	
-	public void hookImageAction() {
-		SWTSkinObject imageObject = skin.getSkinObject("buddies-viewer-nobuddies-graphic");
-		if (null != imageObject) {
-			SWTSkinButtonUtility imageButton = new SWTSkinButtonUtility(imageObject);
-			imageButton.addSelectionListener(new ButtonListenerAdapter() {
-				public void pressed(SWTSkinButtonUtility buttonUtility, SWTSkinObject skinObject, int stateMask) {
-					FriendsToolbar friendsToolbar = (FriendsToolbar) SkinViewManager.getByClass(FriendsToolbar.class);
-					if(friendsToolbar != null) {
-						friendsToolbar.addBuddy();
-					}
-				}
-			});
-		}
-	}
-
-	public boolean isEnabled() {
-		return isEnabled;
-	}
-
-	public void setEnabled(boolean isEnabled) {
-		if (this.isEnabled != isEnabled) {
-			this.isEnabled = isEnabled;
-			avatarsPanel.setEnabled(isEnabled);
-			avatarsPanel.layout(true);
-
-		}
-	}
-
-	public Chat getChat() {
-		return chat;
-	}
-
-	/**
-	 * @return
-	 *
-	 * @since 3.1.1.1
-	 */
-	public Color getColorFileDragBorder() {
-		return colorFileDragBorder;
-	}
-
-	/**
-	 * @return
-	 *
-	 * @since 3.1.1.1
-	 */
-	public Color getColorFileDragBG() {
-		return colorFileDragBG;
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/FriendsToolbar.java b/com/aelitis/azureus/ui/swt/views/skin/FriendsToolbar.java
deleted file mode 100644
index 83c975b..0000000
--- a/com/aelitis/azureus/ui/swt/views/skin/FriendsToolbar.java
+++ /dev/null
@@ -1,907 +0,0 @@
-package com.aelitis.azureus.ui.swt.views.skin;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.config.ParameterListener;
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.shells.*;
-
-import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.VuzeBuddyListener;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.messenger.config.PlatformBuddyMessenger;
-import com.aelitis.azureus.core.messenger.config.PlatformRelayMessenger;
-import com.aelitis.azureus.login.NotLoggedInException;
-import com.aelitis.azureus.ui.skin.SkinConstants;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.shells.friends.AddFriendsPage;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectSash;
-import com.aelitis.azureus.ui.swt.utils.SWTLoginUtils;
-import com.aelitis.azureus.util.ILoginInfoListener;
-import com.aelitis.azureus.util.LoginInfoManager;
-import com.aelitis.azureus.util.LoginInfoManager.LoginInfo;
-
-/**
- * A simple toolbar for the Friends section in the left navigation
- * @author khai
- *
- */
-public class FriendsToolbar
-	extends SkinView
-{
-
-	private Label friendsLabel;
-	private Label friendsCountLabel;
-	
-	private Label onlineFriendsLabel;
-
-	private Label showHideButton;
-
-	private Composite parent;
-
-	private Composite content;
-
-	private Composite shareWithAllPanel;
-
-	private Label edit;
-
-	private Label addFriends;
-
-	private Label image;
-
-	private Label text;
-
-	private int toolbarHeight = 45;
-	
-	private Color friendsTextColor;
-	private Color numberOfFriendsTextColor;
-	private Color secondaryTextColor;
-	private Color hoverTextColor;
-	private Font boldFont;
-	private Font friendsFont;
-
-	private Listener hoverListener;
-	private ImageLoader imageLoader;
-	
-	
-	public FriendsToolbar() {
-	}
-
-	public FriendsToolbar(Composite parent) {
-		this.parent = parent;
-		init();
-	}
-
-	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
-		skin = skinObject.getSkin();
-		parent = (Composite) skinObject.getControl();
-
-		init();
-		return null;
-	}
-
-	private void init() {
-		imageLoader = ImageLoader.getInstance();
-
-		if (null == parent || true == parent.isDisposed()) {
-			throw new NullPointerException("Parent cannot be null or disposed");
-		}
-
-		Layout parentLayout = parent.getLayout();
-		if (null == parentLayout) {
-			parentLayout = new FormLayout();
-			parent.setLayout(parentLayout);
-
-		} else if (false == (parentLayout instanceof FormLayout)) {
-			throw new IllegalArgumentException(
-					"Oops! We can not handle any layout other than FormLayout at the moment!!!");
-		}
-		
-		hoverListener = new Listener() {
-			public void handleEvent(Event event) {
-				Widget widget = event.widget;
-				if(! (widget instanceof Control)) return;
-				Control control = (Control) widget;
-				
-				switch (event.type) {
-				case SWT.MouseEnter:
-						control.setForeground(hoverTextColor);
-					break;
-
-				case SWT.MouseExit:
-						control.setForeground(secondaryTextColor);
-					break;
-				}
-			}
-		};
-
-		content = new Composite(parent, SWT.NONE);
-		content.setBackgroundMode(SWT.INHERIT_DEFAULT);
-		imageLoader.setBackgroundImage(content, "friends_bg");
-		
-		
-		FontData[] datas = content.getFont().getFontData();
-		
-		for(int i = 0 ; i < datas.length ; i++) {
-			datas[i].setStyle(SWT.BOLD);
-			if(Constants.isOSX) {
-				datas[i].setHeight(11);
-			} else {
-				datas[i].setHeight(8);
-			}
-		}
-		
-		boldFont = new Font(content.getDisplay(),datas);
-		
-		for(int i = 0 ; i < datas.length ; i++) {
-			if(Constants.isOSX) {
-				datas[i].setHeight(13);
-			} else {
-				datas[i].setHeight(10);
-			}
-		}
-		
-		friendsFont = new Font(content.getDisplay(),datas);
-		
-		friendsTextColor = new Color(content.getDisplay(),49,52,60);
-		numberOfFriendsTextColor = new Color(content.getDisplay(),77,77,77);
-		secondaryTextColor = new Color(content.getDisplay(),51,63,79);
-		hoverTextColor = new Color(content.getDisplay(),42,63,113);
-		
-		FormData fd = new FormData();
-		fd.top = new FormAttachment(0, 0);
-		fd.height = 46;
-		fd.left = new FormAttachment(0, 0);
-		fd.right = new FormAttachment(100, 0);
-		content.setLayoutData(fd);
-
-		content.setLayout(new FormLayout());
-
-		createControls();
-
-		/*
-		 * KN: Not sure why this must be done at the 'parent' level but without it
-		 * the toolbar is not visible at startup
-		 */
-		parent.getParent().layout(true, true);
-
-		/*
-		 * This height is used to dynamically calculate the percentage of the sash
-		 * the toolbar will occupy
-		 */
-		toolbarHeight = parent.getSize().y - 1;
-
-		/*
-		 * When the sidebar is resized we need to recalculate the percentage for the toolbar again
-		 */
-		SWTSkinObject soSidebar = skin.getSkinObject(SkinConstants.VIEWID_SIDEBAR);
-		if (null != soSidebar) {
-			soSidebar.getControl().addListener(SWT.Resize, new Listener() {
-				public void handleEvent(Event event) {
-					/*
-					 * This is only applicable when the Friends are not visible because when the 
-					 * Friends are visible the percentage for the toolbar is not in use
-					 */
-					if (false == COConfigurationManager.getBooleanParameter("Friends.visible")) {
-						collapseToToolbar();
-					}
-				}
-			});
-		}
-	}
-
-	private void createControls() {
-		FormData data;
-		
-		friendsLabel = new Label(content, SWT.NONE);
-		friendsLabel.setFont(friendsFont);
-		friendsLabel.setForeground(friendsTextColor);
-		friendsLabel.setText(MessageText.getString("v3.buddies.friends"));
-		
-		friendsCountLabel = new Label(content, SWT.NONE);
-		friendsCountLabel.setFont(friendsFont);
-		friendsCountLabel.setForeground(numberOfFriendsTextColor);
-		
-		onlineFriendsLabel = new Label(content, SWT.NONE);
-		onlineFriendsLabel.setFont(boldFont);
-		onlineFriendsLabel.setForeground(secondaryTextColor);
-		
-		showHideButton = new Label(content, SWT.NONE);
-		showHideButton.setData("over",new Boolean(false));
-		Listener hoverBtnListener = new Listener() {
-		public void handleEvent(Event event) {
-			Boolean expandedB = (Boolean) showHideButton.getData("expanded");
-			boolean isExpanded = expandedB != null ? expandedB.booleanValue() : true;
-			
-			switch (event.type) {
-				case SWT.MouseEnter:
-					showHideButton.setData("over",new Boolean(true));
-					imageLoader.setLabelImage(showHideButton, isExpanded
-								? "btn_collapse_over" : "btn_expand_over");
-					break;
-	
-				case SWT.MouseExit:
-					showHideButton.setData("over",new Boolean(false));
-					imageLoader.setLabelImage(showHideButton, isExpanded
-							? "btn_collapse" : "btn_expand");
-					break;
-			}
-			}	
-		};
-		
-		
-		showHideButton.addListener(SWT.MouseEnter, hoverBtnListener);
-		showHideButton.addListener(SWT.MouseExit, hoverBtnListener);
-		
-		
-		data = new FormData();
-		data.left = new FormAttachment(0,8);
-		data.top = new FormAttachment(0,4);
-		friendsLabel.setLayoutData(data);
-		
-		data = new FormData();
-		data.left = new FormAttachment(friendsLabel,2);
-		data.right = new FormAttachment(showHideButton,-5);
-		data.top = new FormAttachment(0,4);
-		friendsCountLabel.setLayoutData(data);
-		
-		data = new FormData();
-		data.right = new FormAttachment(100,-8);
-		data.top = new FormAttachment(0,10);
-		showHideButton.setLayoutData(data);
-
-		hookTuxGoodies(friendsLabel);
-
-		
-		/*
-		 * Initial Friends count
-		 */
-		updateFriendsLabel();
-
-		/*
-		 * Update when the number of Friends changes
-		 */
-		VuzeBuddyManager.addListener(new VuzeBuddyListener() {
-
-			public void buddyRemoved(VuzeBuddy buddy) {
-				Utils.execSWTThread(new AERunnable() {
-					public void runSupport() {
-						updateFriendsLabel();
-					}
-				});
-
-			}
-
-			public void buddyAdded(VuzeBuddy buddy, int position) {
-				Utils.execSWTThread(new AERunnable() {
-					public void runSupport() {
-						updateFriendsLabel();
-					}
-				});
-			}
-
-			public void buddyOrderChanged() {
-				Utils.execSWTThread(new AERunnable() {
-					public void runSupport() {
-						updateFriendsLabel();
-					}
-				});
-			}
-
-			public void buddyChanged(VuzeBuddy buddy) {
-				Utils.execSWTThread(new AERunnable() {
-					public void runSupport() {
-						updateFriendsLabel();
-					}
-				});
-			}
-
-		}, false);
-
-		createToolItems();
-
-		createSharePanel();
-
-		data = new FormData();
-		data.left = new FormAttachment(0,8);
-		data.right = new FormAttachment(edit,-5);
-		data.top = new FormAttachment(0,28);
-		onlineFriendsLabel.setLayoutData(data);	
-		
-		/*
-		 * Initial state from configuration
-		 */
-		boolean isVisible = COConfigurationManager.getBooleanParameter("Friends.visible");
-		SWTSkinObjectSash soSash = (SWTSkinObjectSash) skin.getSkinObject("sidebar-sash-bottom");
-		if (null != soSash) {
-			/*
-			 * If it's visible then it may have a user-defined height so remember it;
-			 * we will use it later when the user expands the Friends area after a collapse
-			 */
-			if (true == isVisible) {
-
-				COConfigurationManager.setParameter("Friends.sash.percent",
-						(float) soSash.getPercent());
-
-			} else {
-
-				collapseToToolbar();
-
-			}
-		}
-		showFooterToggleButton(isVisible);
-
-		/*
-		 * Change button display if the property changes
-		 */
-		COConfigurationManager.addParameterListener("Friends.visible",
-				new ParameterListener() {
-
-					public void parameterChanged(String parameterName) {
-						boolean isVisible = COConfigurationManager.getBooleanParameter("Friends.visible");
-						showFooterToggleButton(isVisible);
-						showFriends(isVisible);
-					}
-				});
-
-		showHideButton.addMouseListener(new MouseAdapter() {
-			public void mouseUp(MouseEvent e) {
-				boolean wasExpanded = COConfigurationManager.getBooleanParameter("Friends.visible");
-				COConfigurationManager.setParameter("Friends.visible", !wasExpanded);
-			}
-		});
-
-	}
-
-	private void createToolItems() {
-
-		edit = new Label(content, SWT.PUSH);
-		edit.setFont(boldFont);
-		edit.setForeground(secondaryTextColor);
-		edit.setCursor(content.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
-		edit.addListener(SWT.MouseEnter, hoverListener);
-		edit.addListener(SWT.MouseExit, hoverListener);
-		edit.setText(MessageText.getString("Button.bar.edit"));
-		edit.addListener(SWT.MouseUp, new Listener() {
-			public void handleEvent(Event arg0) {
-				if (new Boolean(false).equals(edit.getData("edit_mode"))) {
-					setEditMode();
-				} else {
-					reset();
-				}
-			}
-		});
-		
-		LoginInfoManager.getInstance().addListener(new ILoginInfoListener() {
-			public void loginUpdate(LoginInfo info, boolean isNewLoginID) {
-				if (null == info.userName) {
-					Utils.execSWTThreadLater(0, new AERunnable() {
-						public void runSupport() {
-							edit.setText(MessageText.getString("Button.bar.edit"));
-							edit.setData("selection", new Boolean(false));
-							reset();
-							content.layout(true);
-						}
-					});
-
-				}
-			}
-			
-			// @see com.aelitis.azureus.util.ILoginInfoListener#avatarURLUpdated()
-			public void avatarURLUpdated(String newAvatarURL) {
-			}
-		});
-
-		addFriends = new Label(content, SWT.NONE);
-		addFriends.setFont(boldFont);
-		addFriends.setForeground(secondaryTextColor);
-		addFriends.setCursor(content.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
-		addFriends.addListener(SWT.MouseEnter, hoverListener);
-		addFriends.addListener(SWT.MouseExit, hoverListener);
-		addFriends.setText(MessageText.getString("Button.bar.add"));
-		addFriends.addListener(SWT.MouseUp, new Listener() {
-			public void handleEvent(Event arg0) {
-				addBuddy();
-			}
-		});
-		
-		Label separator = new Label(content,SWT.NONE);
-		separator.setFont(boldFont);
-		separator.setForeground(secondaryTextColor);
-		separator.setText("/");
-		
-		FormData data;
-		
-		data = new FormData();
-		data.right = new FormAttachment(100,-8);
-		data.top = new FormAttachment(0,28);
-		addFriends.setLayoutData(data);
-		
-		data = new FormData();
-		data.right = new FormAttachment(addFriends,-1);
-		data.top = new FormAttachment(0,28);
-		separator.setLayoutData(data);
-		
-		
-		data = new FormData();
-		data.right = new FormAttachment(separator,-1);
-		data.top = new FormAttachment(0,28);
-		edit.setLayoutData(data);
-		
-		
-	}
-
-	private void createSharePanel() {
-		/*
-		 * This panel is initially not visible; it will be made visible as needed
-		 */
-		shareWithAllPanel = new Composite(content, SWT.NONE);
-		shareWithAllPanel.setVisible(false);
-		
-		FormData data ;
-		data = new FormData();
-		data.left = new FormAttachment(0,8);
-		data.top = new FormAttachment(0,29);
-		data.right = new FormAttachment(edit,-5);
-		//data.bottom = new FormAttachment(100,-1);
-		shareWithAllPanel.setLayoutData(data);
-		
-		shareWithAllPanel.setLayout(new FormLayout());
-
-		image = new Label(shareWithAllPanel, SWT.NONE);
-		imageLoader.setLabelImage(image, "add_to_share");
-		
-		data = new FormData();
-		data.left = new FormAttachment(0,0);
-		data.top = new FormAttachment(0,0);
-		image.setLayoutData(data);
-
-		text = new Label(shareWithAllPanel, SWT.NONE);
-		text.setFont(boldFont);
-		text.setForeground(secondaryTextColor);
-		text.setText(MessageText.getString("v3.Share.add.buddy.all"));
-		
-		
-		data = new FormData();
-		data.left = new FormAttachment(image,5);
-		data.top = new FormAttachment(0,0);
-		text.setLayoutData(data);
-		
-
-		hookShareListener();
-	}
-
-	private void hookShareListener() {
-		MouseAdapter listener = new MouseAdapter() {
-			boolean shareWithAll = false;
-
-			public void mouseUp(MouseEvent e) {
-				shareWithAll = !shareWithAll;
-				shareAllBuddies(shareWithAll);
-			}
-
-		};
-
-		shareWithAllPanel.addMouseListener(listener);
-		image.addMouseListener(listener);
-		text.addMouseListener(listener);
-	}
-
-	public void enableShareButton(boolean value) {
-		shareWithAllPanel.setEnabled(value);
-		image.setEnabled(value);
-		text.setEnabled(value);
-
-		if (false == value) {
-			BuddiesViewer viewer = (BuddiesViewer) SkinViewManager.getByClass(BuddiesViewer.class);
-			if (null != viewer) {
-				viewer.setMode(BuddiesViewer.disabled_mode);
-			}
-		} else {
-			BuddiesViewer viewer = (BuddiesViewer) SkinViewManager.getByClass(BuddiesViewer.class);
-			if (null != viewer) {
-				viewer.setMode(BuddiesViewer.share_mode);
-			}
-		}
-	}
-
-	protected void shareAllBuddies(boolean value) {
-		BuddiesViewer viewer = (BuddiesViewer) SkinViewManager.getByClass(BuddiesViewer.class);
-		if (null != viewer) {
-			if (true == value) {
-				imageLoader.setLabelImage(image, "add_to_share_selected");
-				viewer.addAllToShare();
-
-			} else {
-				imageLoader.setLabelImage(image, "add_to_share");
-				viewer.removeAllFromShare();
-			}
-		}
-	}
-
-	private void updateFriendsLabel() {
-		
-		if (friendsCountLabel.isDisposed()) {
-			return;
-		}
-		
-		List buddies = VuzeBuddyManager.getAllVuzeBuddies();
-		
-		int onlineBuddies = 0;
-		for(int i = 0 ; i < buddies.size() ; i++) {
-			VuzeBuddy buddy = (VuzeBuddy) buddies.get(i);
-			if(buddy.isOnline(true)) onlineBuddies++;
-		}
-		
-		friendsCountLabel.setText("(" + buddies.size() + ")");
-		
-		onlineFriendsLabel.setText(MessageText.getString("v3.buddies.online",
-				
-				new String[] {
-					onlineBuddies + ""
-				}));
-
-		/*
-		 * The text could be a different length now so do a relayout just in case
-		 */
-		content.layout(true);
-	}
-	
-	public void addBuddy(final String message) {
-		if (!VuzeBuddyManager.isEnabled()) {
-			VuzeBuddyManager.showDisabledDialog();
-			return;
-		}
-
-		SWTLoginUtils.waitForLogin(new SWTLoginUtils.loginWaitListener() {
-			public void loginComplete() {
-				_addBuddy(message);
-			}
-
-		});
-	}
-	
-	public void addBuddy() {
-		addBuddy(null);
-	}
-
-	protected void _addBuddy(final String message) {
-		addFriends.setEnabled(false);
-		showHideButton.setEnabled(false);
-		edit.setEnabled(false);
-
-		BuddiesViewer viewer = (BuddiesViewer) SkinViewManager.getByClass(BuddiesViewer.class);
-		if (null == viewer) {
-			return;
-		}
-		viewer.setMode(BuddiesViewer.add_buddy_mode);
-
-//		SkinView detailPanelView = SkinViewManager.getByClass(DetailPanel.class);
-//		if (detailPanelView instanceof DetailPanel) {
-//			DetailPanel detailPanel = ((DetailPanel) detailPanelView);
-//			detailPanel.show(true, InvitePage.PAGE_ID);
-		//KN: Work in progress for new SHare Wizard			
-		SWTSkinObject soSidebar = skin.getSkinObject("sidebar-sash");//SkinConstants.VIEWID_SIDEBAR);
-		if (null != soSidebar) {
-			MultipageWizard shell = new MultipageWizard(
-					UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell(),
-					SWT.DIALOG_TRIM | SWT.RESIZE) {
-				public void createPages() {
-					AddFriendsPage add = new AddFriendsPage(this);
-					if(message != null) {
-						add.setMessage(message);
-					}
-					addPage(add);
-				}
-			};
-			shell.setText("Vuze - Wizard");
-			shell.setSize(500, 550);
-
-			/*
-			 * TODO: below is the 2 possible ways to open this shell; must pick one before the product is release
-			 */
-			boolean useDocker = false;
-
-			if (true == useDocker) {
-
-				/*
-				 * Use a shelldocker to 'dock' the shell; this is currently configured to dock on the right
-				 * side of the main vertical sash.  Notice that if you move of resize the main application
-				 * the docking behavior is adjusted accordingly
-				 */
-				ShellDocker docker = new ShellDocker(soSidebar.getControl(),
-						shell.getShell());
-				docker.setAnchorControlPosition(new DockPosition(
-						DockPosition.BOTTOM_RIGHT, new Offset(1, -shell.getSize().y)));
-				docker.openShell(true, false);
-
-			} else {
-
-				/*
-				 * Opens a centered free-floating shell
-				 */
-
-				UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-				if (null == uiFunctions) {
-					/*
-					 * Centers on the active monitor
-					 */
-					Utils.centreWindow(shell.getShell());
-				} else {
-					/*
-					 * Centers on the main application window
-					 */
-					Utils.centerWindowRelativeTo(shell.getShell(),
-							uiFunctions.getMainShell());
-				}
-
-				shell.open();
-			}
-		}
-	}
-
-	public void reset() {
-		onlineFriendsLabel.setVisible(true);
-		addFriends.setEnabled(true);
-		friendsLabel.setEnabled(true);
-		showHideButton.setEnabled(true);
-		edit.setEnabled(true);
-		edit.setText(MessageText.getString("Button.bar.edit"));
-		edit.setData("edit_mode",new Boolean(false));
-
-		BuddiesViewer viewer = (BuddiesViewer) SkinViewManager.getByClass(BuddiesViewer.class);
-		if (null == viewer) {
-			return;
-		}
-		viewer.setMode(BuddiesViewer.none_active_mode);
-
-		shareWithAllPanel.setVisible(false);
-		content.layout(true);
-
-	}
-
-	public void setShareMode() {
-		BuddiesViewer viewer = (BuddiesViewer) SkinViewManager.getByClass(BuddiesViewer.class);
-		if (null == viewer) {
-			return;
-		}
-		
-		viewer.setMode(BuddiesViewer.share_mode);
-		addFriends.setEnabled(false);
-		onlineFriendsLabel.setVisible(false);
-		showHideButton.setEnabled(false);
-		edit.setEnabled(false);
-
-		shareWithAllPanel.setVisible(true);
-		content.layout(true);
-
-		COConfigurationManager.setParameter("Friends.visible", true);
-
-	}
-
-	public void setAddFriendsMode() {
-
-		SWTLoginUtils.waitForLogin(new SWTLoginUtils.loginWaitListener() {
-
-			public void loginComplete() {
-				BuddiesViewer viewer = (BuddiesViewer) SkinViewManager.getByClass(BuddiesViewer.class);
-				if (null == viewer) {
-					return;
-				}
-				viewer.setMode(BuddiesViewer.share_mode);
-				addFriends.setEnabled(false);
-				showHideButton.setEnabled(false);
-				edit.setEnabled(false);
-
-				shareWithAllPanel.setVisible(true);
-			}
-
-			public long getCancelDelay() {
-				return 0;
-			}
-
-			public void loginCanceled() {
-				reset();
-			}
-
-		});
-
-	}
-
-	public void setEditMode() {
-		SWTLoginUtils.waitForLogin(new SWTLoginUtils.loginWaitListener() {
-
-			public void loginComplete() {
-				COConfigurationManager.setParameter("Friends.visible", true);
-				BuddiesViewer viewer = (BuddiesViewer) SkinViewManager.getByClass(BuddiesViewer.class);
-				if (null == viewer) {
-					return;
-				}
-				viewer.setMode(BuddiesViewer.edit_mode);
-
-				
-				edit.setData("edit_mode",new Boolean(true));
-				
-				edit.setText(MessageText.getString("Button.bar.edit.cancel"));
-				edit.setEnabled(true);
-				addFriends.setEnabled(false);
-				showHideButton.setEnabled(false);
-				content.layout(true);
-			}
-
-			public long getCancelDelay() {
-				return 0;
-			}
-
-			public void loginCanceled() {
-				reset();
-			}
-
-		});
-	}
-
-	/**
-	 * Toggles between showing the 'collapse' or 'expand' buttons
-	 * @param value
-	 */
-	private void showFooterToggleButton(boolean isExpanded) {
-		showHideButton.setData("expanded",new Boolean(isExpanded));
-		
-		Boolean overB = (Boolean) showHideButton.getData("over");
-		boolean isOver = overB != null ? overB.booleanValue() : false;
-		
-		if(isOver) {
-			imageLoader.setLabelImage(showHideButton, isExpanded
-					? "btn_collapse_over" : "btn_expand_over");
-		} else {
-			imageLoader.setLabelImage(showHideButton, isExpanded
-					? "btn_collapse" : "btn_expand");
-		}
-
-	}
-
-	/**
-	 * Here we collapse or expand the bottom sash of the sidebar
-	 * @param isExpanded
-	 */
-	public void showFriends(final boolean isExpanded) {
-
-		/*
-		 * To hide a sash we typically set it's percentage to 0 but since this bottom
-		 * sash has a toolbar that we want to always be visible we use the toolbar's height
-		 * then calculate that as a percentage of the total height of the side bar; we use this 
-		 * as the percentage when 'collapsed'
-		 * 
-		 * Additionally when collapsed we make the sash invisible and turn it back to visible when
-		 * it's expanded.
-		 */
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				SWTSkinObjectSash soSash = (SWTSkinObjectSash) skin.getSkinObject("sidebar-sash-bottom");
-
-				if (true == isExpanded) {
-
-					soSash.setVisible(true);
-					soSash.setPercent((double) COConfigurationManager.getFloatParameter("Friends.sash.percent"));
-
-				} else {
-
-					COConfigurationManager.setParameter("Friends.sash.percent",
-							(float) soSash.getPercent());
-
-					collapseToToolbar();
-
-				}
-			}
-		});
-	}
-
-	private void collapseToToolbar() {
-
-		SWTSkinObject soSidebar = skin.getSkinObject(SkinConstants.VIEWID_SIDEBAR);
-		if (null != soSidebar) {
-			SWTSkinObjectSash soSash = (SWTSkinObjectSash) skin.getSkinObject("sidebar-sash-bottom");
-			/*
-			 * Hide the sash if the Friends viewer is not visible
-			 */
-			soSash.setVisible(false);
-			soSash.setBelowPX(toolbarHeight);
-		}
-	}
-
-	private void hookTuxGoodies(Control control) {
-		if (!org.gudy.azureus2.core3.util.Constants.isCVSVersion()) {
-			return;
-		}
-		Menu menu = new Menu(control);
-		MenuItem menuItem;
-		menuItem = new MenuItem(menu, SWT.PUSH);
-		menuItem.setText("buddy sync up");
-		menuItem.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				if (!LoginInfoManager.getInstance().isLoggedIn()) {
-					Utils.openMessageBox(null, SWT.ICON_ERROR, "No",
-							"not logged in. no can do");
-					return;
-				}
-				try {
-					PlatformRelayMessenger.fetch(0);
-					PlatformBuddyMessenger.sync(null);
-					PlatformBuddyMessenger.getInvites();
-				} catch (NotLoggedInException e1) {
-				}
-			}
-		});
-
-		menuItem = new MenuItem(menu, SWT.PUSH);
-		menuItem.setText("send msg to all buddies");
-		menuItem.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				if (!LoginInfoManager.getInstance().isLoggedIn()) {
-					Utils.openMessageBox(null, SWT.ICON_ERROR, "No",
-							"not logged in. no can do");
-					return;
-				}
-
-				SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow();
-				entryWindow.setTitle("Moo");
-				entryWindow.setMessage("Message:");
-				entryWindow.prompt();
-				if (!entryWindow.hasSubmittedInput()) {
-					return;
-				}
-				String txt = entryWindow.getSubmittedInput();
-
-				if (txt != null) {
-					VuzeActivitiesEntry entry = new VuzeActivitiesEntry(
-							SystemTime.getCurrentTime(), txt, "Test");
-					List buddies = VuzeBuddyManager.getAllVuzeBuddies();
-					for (Iterator iter = buddies.iterator(); iter.hasNext();) {
-						VuzeBuddy buddy = (VuzeBuddy) iter.next();
-						System.out.println("sending to " + buddy.getDisplayName());
-						try {
-							buddy.sendActivity(entry);
-						} catch (NotLoggedInException e1) {
-							Debug.out("Shouldn't Happen", e1);
-						}
-					}
-				}
-			}
-		});
-		
-		menuItem = new MenuItem(menu, SWT.PUSH);
-		menuItem.setText("filter");
-		menuItem.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				BuddiesViewer viewer = (BuddiesViewer) SkinViewManager.getByClass(BuddiesViewer.class);
-				if (null != viewer) {
-					viewer.openFilterDialog();
-				}
-			}
-		});
-		
-
-
-		control.setMenu(menu);
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/MyTorrentsView_Big.java b/com/aelitis/azureus/ui/swt/views/skin/MyTorrentsView_Big.java
index 594ba34..dda89a7 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/MyTorrentsView_Big.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/MyTorrentsView_Big.java
@@ -39,8 +39,7 @@ public class MyTorrentsView_Big
 	
 
 	public boolean isOurDownloadManager(DownloadManager dm) {
-		if (PlatformTorrentUtils.getAdId(dm.getTorrent()) != null ||
-				PlatformTorrentUtils.isUpdateDM(dm)) {
+		if (PlatformTorrentUtils.isUpdateDM(dm)) {
 			return false;
 		}
 		
@@ -49,7 +48,7 @@ public class MyTorrentsView_Big
 				return false;
 			}
 		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_ALL) {
-			return isInCurrentCategory(dm) && filterCheck(dm);
+			return isInCurrentCategory(dm);
 		}
 		
 		return super.isOurDownloadManager(dm);
diff --git a/com/aelitis/azureus/ui/swt/views/skin/Publish.java b/com/aelitis/azureus/ui/swt/views/skin/Publish.java
deleted file mode 100644
index b659e58..0000000
--- a/com/aelitis/azureus/ui/swt/views/skin/Publish.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * Copyright (C) 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package com.aelitis.azureus.ui.swt.views.skin;
-
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.ui.skin.SkinConstants;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectBrowser;
-import com.aelitis.azureus.util.ConstantsVuze;
-import com.aelitis.azureus.util.ContentNetworkUtils;
-
-/**
- * @author TuxPaper
- * @created Oct 1, 2006
- *
- */
-public class Publish
-	extends SkinView
-{
-	private SWTSkinObjectBrowser browserSkinObject;
-
-	public Object skinObjectInitialShow(final SWTSkinObject skinObject, Object params) {
-		browserSkinObject = (SWTSkinObjectBrowser) skin.getSkinObject(
-				SkinConstants.VIEWID_BROWSER_PUBLISH, soMain);
-		
-		Object o = skinObject.getData("CreationParams");
-		if (o instanceof String) {
-			browserSkinObject.setURL((String) o);
-		} else {
-  		String sURL = ContentNetworkUtils.getUrl(
-					ConstantsVuze.getDefaultContentNetwork(), ContentNetwork.SERVICE_PUBLISH);
-  		browserSkinObject.setURL(sURL);
-		}
-
-		return null;
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SBC_ActivityTableView.java b/com/aelitis/azureus/ui/swt/views/skin/SBC_ActivityTableView.java
index 2e18c05..cb9aad0 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SBC_ActivityTableView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SBC_ActivityTableView.java
@@ -24,14 +24,11 @@ import java.util.List;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.KeyEvent;
 import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.graphics.Cursor;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Shell;
 
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.ui.tables.TableManager;
 import org.gudy.azureus2.ui.swt.IconBarEnabler;
 import org.gudy.azureus2.ui.swt.Utils;
@@ -40,7 +37,7 @@ import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
 
 import com.aelitis.azureus.activities.*;
-import com.aelitis.azureus.ui.common.RememberedDecisionsManager;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 import com.aelitis.azureus.ui.common.table.*;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
@@ -273,77 +270,64 @@ public class SBC_ActivityTableView
 		}
 	}
 
-	protected void removeSelected() {
-		Shell shell = view.getComposite().getShell();
-		Cursor oldCursor = shell.getCursor();
-		try {
-			Object[] selectedDataSources = view.getSelectedDataSources().toArray();
-			VuzeActivitiesEntry[] entriesToRemove = new VuzeActivitiesEntry[selectedDataSources.length];
-			int entriesToRemovePos = 0;
-
-			shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
-			int rememberedDecision = RememberedDecisionsManager.getRememberedDecision(tableID
-					+ "-Remove");
-			if (rememberedDecision == 0) {
-				try {
-					for (int i = 0; i < selectedDataSources.length; i++) {
-						if (selectedDataSources[i] instanceof VuzeActivitiesEntry) {
-							VuzeActivitiesEntry entry = (VuzeActivitiesEntry) selectedDataSources[i];
-							boolean isHeader = VuzeActivitiesConstants.TYPEID_HEADER.equals(entry.getTypeID());
-							if (isHeader) {
-								continue;
-							}
-
-							entriesToRemove[entriesToRemovePos++] = entry;
-						}
-					}
-				} catch (Exception e) {
-					Debug.out(e);
+	private void removeEntries(final VuzeActivitiesEntry[] toRemove, final int startIndex) {
+		final VuzeActivitiesEntry entry = toRemove[startIndex];
+		if (entry == null || VuzeActivitiesConstants.TYPEID_HEADER.equals(entry.getTypeID())) {
+			int nextIndex = startIndex + 1;
+			if (nextIndex < toRemove.length) {
+				removeEntries(toRemove, nextIndex);
+			}
+			return;
+		}
+
+		MessageBoxShell mb = new MessageBoxShell(
+				MessageText.getString("v3.activity.remove.title"),
+				MessageText.getString("v3.activity.remove.text",
+						new String[] {
+							entry.getText()
+						}));
+		mb.setRemember(tableID + "-Remove", false,
+				MessageText.getString("MessageBoxWindow.nomoreprompting"));
+
+		if (startIndex == toRemove.length - 1) {
+			mb.setButtons(0, new String[] {
+				MessageText.getString("Button.yes"),
+				MessageText.getString("Button.no"),
+			}, new Integer[] { 0, 1 });
+			mb.setRememberOnlyIfButton(0);
+		} else {
+			mb.setButtons(1, new String[] {
+				MessageText.getString("Button.removeAll"),
+				MessageText.getString("Button.yes"),
+				MessageText.getString("Button.no"),
+			}, new Integer[] { 2, 0, 1 });
+			mb.setRememberOnlyIfButton(1);
+		}
+		
+		mb.setHandleHTML(false);
+		mb.open(new UserPrompterResultListener() {
+			public void prompterClosed(int result) {
+				if (result == 2) {
+					int numToRemove = toRemove.length - startIndex;
+					VuzeActivitiesEntry[] toGroupRemove = new VuzeActivitiesEntry[numToRemove];
+					System.arraycopy(toRemove, startIndex, toGroupRemove, 0, numToRemove);
+					VuzeActivitiesManager.removeEntries(toGroupRemove);
+					return;
+				} else if (result == 0) {
+					VuzeActivitiesManager.removeEntries(new VuzeActivitiesEntry[] { entry } );
 				}
-			} else {
-				try {
-					for (int i = 0; i < selectedDataSources.length; i++) {
-						if (selectedDataSources[i] instanceof VuzeActivitiesEntry) {
-							VuzeActivitiesEntry entry = (VuzeActivitiesEntry) selectedDataSources[i];
-							boolean isHeader = VuzeActivitiesConstants.TYPEID_HEADER.equals(entry.getTypeID());
-							if (isHeader) {
-								continue;
-							}
-
-							MessageBoxShell mb = new MessageBoxShell(Utils.findAnyShell(),
-									MessageText.getString("v3.activity.remove.title"),
-									MessageText.getString("v3.activity.remove.text",
-											new String[] {
-												entry.getText()
-											}), new String[] {
-										MessageText.getString("Button.yes"),
-										MessageText.getString("Button.no")
-									}, 0, tableID + "-Remove",
-									MessageText.getString("MessageBoxWindow.nomoreprompting"),
-									false, 0);
-							mb.setRememberOnlyIfButton(0);
-							mb.setHandleHTML(false);
-							int result = mb.open();
-							if (result == 0) {
-								entriesToRemove[entriesToRemovePos++] = entry;
-							} else if (result == -1) {
-								break;
-							}
-						}
-					}
-				} catch (Exception e) {
-					Debug.out(e);
+
+				int nextIndex = startIndex + 1;
+				if (nextIndex < toRemove.length) {
+					removeEntries(toRemove, nextIndex);
 				}
 			}
+		});
+	}
 
-			if (entriesToRemovePos > 0) {
-				VuzeActivitiesManager.removeEntries(entriesToRemove);
-			}
-		} catch (Exception e) {
-			Debug.out(e);
-		} finally {
-			shell.setCursor(oldCursor);
-		}
+	protected void removeSelected() {
+		VuzeActivitiesEntry[] selectedEntries = view.getSelectedDataSources().toArray(new VuzeActivitiesEntry[0]);
+		removeEntries(selectedEntries, 0);
 	}
 	
 	public TableViewSWT getView() {
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryTableView.java b/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryTableView.java
index 662e551..72ea0a2 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryTableView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryTableView.java
@@ -22,20 +22,22 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.events.KeyEvent;
 import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.widgets.Composite;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.plugins.ui.tables.TableRow;
+import org.gudy.azureus2.plugins.ui.tables.TableRowRefreshListener;
 import org.gudy.azureus2.ui.swt.IconBarEnabler;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.views.IView;
 import org.gudy.azureus2.ui.swt.views.MyTorrentsSuperView;
 import org.gudy.azureus2.ui.swt.views.MyTorrentsView;
@@ -46,7 +48,9 @@ import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnCreator;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 
-import com.aelitis.azureus.core.*;
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.UIFunctions;
@@ -57,7 +61,6 @@ import com.aelitis.azureus.ui.common.table.TableSelectionAdapter;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfo;
 import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfoContentNetwork;
-import com.aelitis.azureus.ui.swt.Initializer;
 import com.aelitis.azureus.ui.swt.columns.utils.TableColumnCreatorV3;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
@@ -67,10 +70,6 @@ import com.aelitis.azureus.util.DLReferals;
 import com.aelitis.azureus.util.DataSourceUtils;
 import com.aelitis.azureus.util.PlayUtils;
 
-import org.gudy.azureus2.plugins.ui.tables.TableManager;
-import org.gudy.azureus2.plugins.ui.tables.TableRow;
-import org.gudy.azureus2.plugins.ui.tables.TableRowRefreshListener;
-
 /**
  * Classic My Torrents view wrapped in a SkinView
  * 
@@ -187,7 +186,25 @@ public class SBC_LibraryTableView
 				});
 			}
 		}
-		
+
+		SWTSkinObjectContainer soContents = new SWTSkinObjectContainer(skin,
+				skin.getSkinProperties(), getUpdateUIName(), "", soMain);
+
+		skin.layout();
+
+		viewComposite = soContents.getComposite();
+		viewComposite.setBackground(viewComposite.getDisplay().getSystemColor(
+				SWT.COLOR_WIDGET_BACKGROUND));
+		viewComposite.setForeground(viewComposite.getDisplay().getSystemColor(
+				SWT.COLOR_WIDGET_FOREGROUND));
+		viewComposite.setLayoutData(Utils.getFilledFormData());
+		GridLayout gridLayout = new GridLayout();
+		gridLayout.horizontalSpacing = gridLayout.verticalSpacing = gridLayout.marginHeight = gridLayout.marginWidth = 0;
+		viewComposite.setLayout(gridLayout);
+
+		view.initialize(viewComposite);
+
+
 		if (tv == null) {
 			if (view instanceof TableViewTab) {
 				TableViewTab tvt = (TableViewTab) view;
@@ -197,6 +214,15 @@ public class SBC_LibraryTableView
 			}
 		}
 		
+		SWTSkinObject soSizeSlider = skin.getSkinObject("table-size-slider", soParent.getParent());
+		if (soSizeSlider instanceof SWTSkinObjectContainer) {
+			SWTSkinObjectContainer so = (SWTSkinObjectContainer) soSizeSlider;
+			if (tv != null && !tv.enableSizeSlider(so.getComposite(), 16, 100)) {
+				so.setVisible(false);
+			}
+		}
+
+		
 		if (torrentFilterMode == SBC_LibraryView.TORRENTS_ALL
 				&& tv != null) {
 			tv.addRefreshListener(new TableRowRefreshListener() {
@@ -236,8 +262,8 @@ public class SBC_LibraryTableView
 								if (contentHash != null && contentHash.length() > 0) {
 									ContentNetwork cn = DataSourceUtils.getContentNetwork(torrent);
 									if (cn == null) {
-										Utils.openMessageBox(null, SWT.OK, "coq",
-												"Not in Content Network List");
+										new MessageBoxShell(SWT.OK, "coq",
+												"Not in Content Network List").open(null);
 										return;
 									}
 									String url = cn.getTorrentDownloadService(contentHash, "coq");
@@ -249,36 +275,10 @@ public class SBC_LibraryTableView
 
 							}
 						}
-					} else if (e.character == 18 && e.stateMask == (SWT.SHIFT | SWT.CONTROL)) {
-						Object[] selectedDataSources = tv.getSelectedDataSources().toArray();
-						for (int i = 0; i < selectedDataSources.length; i++) {
-							DownloadManager dm = (DownloadManager) selectedDataSources[i];
-							if (dm != null) {
-								PlatformTorrentUtils.setContentLastUpdated(dm.getTorrent(), 0);
-								PlatformTorrentUtils.updateMetaData(dm.getTorrent(), 0);
-							}
-						}
 					}
 				}
 			});
 		}
-		
-		SWTSkinObjectContainer soContents = new SWTSkinObjectContainer(skin,
-				skin.getSkinProperties(), getUpdateUIName(), "", soMain);
-
-		skin.layout();
-
-		viewComposite = soContents.getComposite();
-		viewComposite.setBackground(viewComposite.getDisplay().getSystemColor(
-				SWT.COLOR_WIDGET_BACKGROUND));
-		viewComposite.setForeground(viewComposite.getDisplay().getSystemColor(
-				SWT.COLOR_WIDGET_FOREGROUND));
-		viewComposite.setLayoutData(Utils.getFilledFormData());
-		GridLayout gridLayout = new GridLayout();
-		gridLayout.horizontalSpacing = gridLayout.verticalSpacing = gridLayout.marginHeight = gridLayout.marginWidth = 0;
-		viewComposite.setLayout(gridLayout);
-
-		view.initialize(viewComposite);
 
 		if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
 			SWTSkinObject so = skin.getSkinObject("library-list-button-right",
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryView.java b/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryView.java
index e6c4f48..863983a 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryView.java
@@ -18,7 +18,6 @@
 
 package com.aelitis.azureus.ui.swt.views.skin;
 
-import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
@@ -40,8 +39,8 @@ import org.gudy.azureus2.plugins.ui.tables.TableManager;
 import org.gudy.azureus2.ui.swt.Utils;
 
 import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.networkmanager.NetworkManager;
 import com.aelitis.azureus.core.speedmanager.SpeedManager;
 import com.aelitis.azureus.core.torrent.HasBeenOpenedListener;
@@ -52,7 +51,9 @@ import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 import com.aelitis.azureus.ui.skin.SkinConstants;
 import com.aelitis.azureus.ui.swt.Initializer;
-import com.aelitis.azureus.ui.swt.skin.*;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectText;
 import com.aelitis.azureus.ui.swt.toolbar.ToolBarItem;
 import com.aelitis.azureus.ui.swt.toolbar.ToolBarItemListener;
 import com.aelitis.azureus.ui.swt.utils.ColorCache;
@@ -82,10 +83,6 @@ public class SBC_LibraryView
 
 	public static final int TORRENTS_UNOPENED = 3;
 	
-	private static final String CFG_INFOBAR = "Library.infobar";
-
-	public static List allViews = new ArrayList(1);
-
 	private final static String[] modeViewIDs = {
 		SkinConstants.VIEWID_SIDEBAR_LIBRARY_BIG,
 		SkinConstants.VIEWID_SIDEBAR_LIBRARY_SMALL
@@ -138,10 +135,6 @@ public class SBC_LibraryView
 
 	private ToolBarItem itemModeBig;
 
-	private SWTSkinObject skinObject;
-
-	private InfoBarUtil infoBarUtil;
-
 	private SWTSkinObject soWait;
 	
 	private SWTSkinObject soWaitProgress;
@@ -152,8 +145,6 @@ public class SBC_LibraryView
 
 	// @see com.aelitis.azureus.ui.swt.views.skin.SkinView#showSupport(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
 	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
-		this.skinObject = skinObject;
-		
 		soWait = null;
 		try {
 			soWait = getSkinObject("library-wait");
@@ -164,10 +155,10 @@ public class SBC_LibraryView
 					public void paintControl(PaintEvent e) {
 						Control c = (Control) e.widget;
 						Point size = c.getSize();
-						e.gc.setBackground(ColorCache.getColor(e.display, "#0000ff"));
+						e.gc.setBackground(ColorCache.getColor(e.display, "#23a7df"));
 						int breakX = size.x * waitProgress / 100;
 						e.gc.fillRectangle(0, 0, breakX, size.y);
-						e.gc.setBackground(ColorCache.getColor(e.display, "#808080"));
+						e.gc.setBackground(ColorCache.getColor(e.display, "#cccccc"));
 						e.gc.fillRectangle(breakX, 0, size.x - breakX, size.y);
 					}
 				});
@@ -381,19 +372,6 @@ public class SBC_LibraryView
 			COConfigurationManager.setParameter(torrentFilter + ".viewmode", viewMode);
 		}
 
-		if (torrentFilterMode == TORRENTS_ALL && viewMode == 0 && infoBarUtil == null) {
-			infoBarUtil = new InfoBarUtil(skinObject, true, CFG_INFOBAR,
-					"v3.library.infobar") {
-				public boolean allowShow() {
-					return true;
-				}
-			};
-		} else if (infoBarUtil != null) {
-			if (torrentFilterMode != TORRENTS_ALL || viewMode != 0) {
-				infoBarUtil.hide(true);
-			}
-		}
-		
 		String entryID = null;
 		if (torrentFilterMode == TORRENTS_ALL) {
 			entryID = SideBar.SIDEBAR_SECTION_LIBRARY;
@@ -507,8 +485,7 @@ public class SBC_LibraryView
 		final GlobalManager gm = core.getGlobalManager();
 		final DownloadManagerListener dmListener = new DownloadManagerAdapter() {
 			public void stateChanged(DownloadManager dm, int state) {
-				if (PlatformTorrentUtils.getAdId(dm.getTorrent()) != null
-						|| PlatformTorrentUtils.isUpdateDM(dm)) {
+				if (PlatformTorrentUtils.isUpdateDM(dm)) {
 					return;
 				}
 				if (dm.getAssumedComplete()) {
@@ -558,8 +535,7 @@ public class SBC_LibraryView
 			}
 			
 			public void completionChanged(DownloadManager dm, boolean completed) {
-				if (PlatformTorrentUtils.getAdId(dm.getTorrent()) != null
-						|| PlatformTorrentUtils.isUpdateDM(dm)) {
+				if (PlatformTorrentUtils.isUpdateDM(dm)) {
 					return;
 				}
 				if (completed) {
@@ -634,8 +610,7 @@ public class SBC_LibraryView
 		
 		gm.addListener(new GlobalManagerAdapter() {
 			public void downloadManagerRemoved(DownloadManager dm) {
-				if (PlatformTorrentUtils.getAdId(dm.getTorrent()) != null
-						|| PlatformTorrentUtils.isUpdateDM(dm)) {
+				if (PlatformTorrentUtils.isUpdateDM(dm)) {
 					return;
 				}
 				recountUnopened();
@@ -657,8 +632,7 @@ public class SBC_LibraryView
 			}
 			
 			public void downloadManagerAdded(DownloadManager dm) {
-				if (PlatformTorrentUtils.getAdId(dm.getTorrent()) != null
-						|| PlatformTorrentUtils.isUpdateDM(dm)) {
+				if (PlatformTorrentUtils.isUpdateDM(dm)) {
 					return;
 				}
 				dm.addListener(dmListener, false);
@@ -684,8 +658,7 @@ public class SBC_LibraryView
 		List downloadManagers = gm.getDownloadManagers();
 		for (Iterator iter = downloadManagers.iterator(); iter.hasNext();) {
 			DownloadManager dm = (DownloadManager) iter.next();
-			if (PlatformTorrentUtils.getAdId(dm.getTorrent()) != null
-					|| PlatformTorrentUtils.isUpdateDM(dm)) {
+			if (PlatformTorrentUtils.isUpdateDM(dm)) {
 				continue;
 			}
 			dm.addListener(dmListener, false);
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SearchResultsTabArea.java b/com/aelitis/azureus/ui/swt/views/skin/SearchResultsTabArea.java
index c0915c1..59865f0 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SearchResultsTabArea.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SearchResultsTabArea.java
@@ -35,6 +35,7 @@ import org.eclipse.swt.widgets.Shell;
 
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.ui.UIManager;
@@ -43,6 +44,7 @@ import org.gudy.azureus2.plugins.ui.sidebar.SideBarVitalityImage;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.PropertiesWindow;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
 import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
 
 import com.aelitis.azureus.core.AzureusCore;
@@ -51,6 +53,7 @@ import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.metasearch.Engine;
 import com.aelitis.azureus.core.metasearch.MetaSearchManagerFactory;
 import com.aelitis.azureus.core.metasearch.impl.web.WebEngine;
+import com.aelitis.azureus.core.metasearch.impl.web.json.JSONEngine;
 import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
 import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
 import com.aelitis.azureus.ui.skin.SkinConstants;
@@ -269,6 +272,39 @@ public class SearchResultsTabArea
 									});
 							}
 							
+							if ( Constants.IS_CVS_VERSION ){
+								
+								MenuItem copy_mi = menuManager.addMenuItem( engine_menu, "ConfigView.copy.to.clipboard.tooltip" );
+	
+								copy_mi.addListener(
+									new MenuItemListener()
+									{
+										public void 
+										selected(
+											MenuItem menu, 
+											Object target) 
+										{
+											final Shell shell = Utils.findAnyShell();
+											
+											shell.getDisplay().asyncExec(
+												new AERunnable() 
+												{
+													public void 
+													runSupport()
+													{
+														try{
+															ClipboardCopy.copyToClipBoard( engine.exportToJSONString());
+															
+														}catch( Throwable e ){
+															
+															Debug.out( e );
+														}
+													}
+												});
+										}
+									});
+							}
+							
 							if ( engine instanceof WebEngine ){
 								
 								final WebEngine we = (WebEngine)engine;
@@ -421,6 +457,10 @@ public class SearchResultsTabArea
 						
 						browser.addTitleListener(new TitleListener() {
 							public void changed(TitleEvent event) {
+								if (event.widget.isDisposed()
+										|| ((Browser) event.widget).getShell().isDisposed()) {
+									return;
+								}
 								title = event.title;
 								int i = title.toLowerCase().indexOf("details:");
 								if (i > 0) {
diff --git a/com/aelitis/azureus/ui/swt/views/skin/ToolBarView.java b/com/aelitis/azureus/ui/swt/views/skin/ToolBarView.java
index 41ccf08..6022ea1 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/ToolBarView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/ToolBarView.java
@@ -31,7 +31,6 @@ import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.global.GlobalManager;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 import org.gudy.azureus2.ui.swt.IconBarEnabler;
@@ -47,6 +46,7 @@ import com.aelitis.azureus.core.devices.TranscodeException;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.common.table.TableView;
 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.ISelectedVuzeFileContent;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentListener;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
@@ -216,23 +216,6 @@ public class ToolBarView
   		first = false;
 		}
 
-		// ==share
-		item = new ToolBarItem("share", "image.button.share", "iconBar.share") {
-			// @see com.aelitis.azureus.ui.swt.toolbar.ToolBarItem#triggerToolBarItem()
-			public void triggerToolBarItem() {
-				String viewID = SelectedContentManager.getCurrentySelectedViewID();
-				if (viewID == null && triggerIViewToolBar(getId())) {
-					return;
-				}
-				ISelectedContent[] contents = SelectedContentManager.getCurrentlySelectedContent();
-				if (contents.length > 0) {
-					VuzeShareUtils.getInstance().shareContent(contents[0], null, "ToolBar");
-				}
-			}
-		};
-		addToolBarItem(item, first ? "toolbar.area.sitem.left" : "toolbar.area.sitem", so2nd);
-		addSeperator(so2nd);
-
 		// ==run
 		item = new ToolBarItem("run", "image.toolbar.run", "iconBar.run") {
 			public void triggerToolBarItem() {
@@ -659,7 +642,6 @@ public class ToolBarView
 				String[] TBKEYS = new String[] {
 					"download",
 					"play",
-					"share",
 					"run",
 					"up",
 					"down",
@@ -722,13 +704,6 @@ public class ToolBarView
 			}
 		}
 
-		item = getToolBarItem("share");
-		if (item != null) {
-			boolean canShare = has1SelectionWithHash
-					&& VuzeShareUtils.getInstance().canShare(currentContent[0]);
-			item.setEnabled(canShare);
-		}
-
 		item = getToolBarItem("run");
 		if (item != null) {
 			boolean canRun = has1Selection;
@@ -756,9 +731,6 @@ public class ToolBarView
 
 						canRun = false;
 
-					} else if (PlatformTorrentUtils.getAdId(torrent) != null) {
-
-						canRun = false;
 					}
 				}
 			}
@@ -775,11 +747,12 @@ public class ToolBarView
 		}
 		item = getToolBarItem("play");
 		if (item != null) {
-			item.setEnabled(has1Selection && PlayUtils.canPlayDS(currentContent[0]));
+			item.setEnabled(has1Selection && (!(currentContent[0] instanceof ISelectedVuzeFileContent )) && PlayUtils.canPlayDS(currentContent[0]));
 		}
 		item = getToolBarItem("download");
 		if (item != null) {
 			boolean enabled = has1Selection
+					&& (!(currentContent[0] instanceof ISelectedVuzeFileContent ))
 					&& currentContent[0].getDownloadManager() == null
 					&& (currentContent[0].getHash() != null || currentContent[0].getDownloadInfo() != null);
 			item.setEnabled(enabled);
@@ -845,13 +818,21 @@ public class ToolBarView
 		} else {
 			SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
 			if (sidebar != null) {
+				ToolBarItem[] allToolBarItems = getAllToolBarItems();
 				SideBarEntrySWT entry = sidebar.getCurrentEntry();
 				IconBarEnabler enabler = entry.getIconBarEnabler();
-				if (enabler == null && entry.iview != null) {
-					enabler = entry.iview;
+				if (enabler == null) {
+					if (entry.iview != null) {
+						enabler = entry.iview;
+					} else {
+						for (int i = 0; i < allToolBarItems.length; i++) {
+							ToolBarItem toolBarItem = allToolBarItems[i];
+							toolBarItem.setEnabled(false);
+						}
+						return;
+					}
 				}
 
-				ToolBarItem[] allToolBarItems = getAllToolBarItems();
 				for (int i = 0; i < allToolBarItems.length; i++) {
 					ToolBarItem toolBarItem = allToolBarItems[i];
 					toolBarItem.setEnabled(enabler.isEnabled(toolBarItem.getId()));
diff --git a/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java b/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java
index 1fdc4df..190af45 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java
@@ -54,13 +54,13 @@ import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.download.DownloadManagerEnhancer;
 import com.aelitis.azureus.core.download.EnhancedDownloadManager;
-import com.aelitis.azureus.core.messenger.config.PlatformDCAdManager;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.core.vuzefile.VuzeFile;
 import com.aelitis.azureus.core.vuzefile.VuzeFileComponent;
 import com.aelitis.azureus.core.vuzefile.VuzeFileHandler;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 import com.aelitis.azureus.ui.common.table.TableRowCore;
 import com.aelitis.azureus.ui.common.table.TableView;
 import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfo;
@@ -73,11 +73,9 @@ import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility;
 import com.aelitis.azureus.ui.swt.utils.TorrentUIUtilsV3;
 import com.aelitis.azureus.util.ContentNetworkUtils;
-import com.aelitis.azureus.util.DCAdManager;
 import com.aelitis.azureus.util.DLReferals;
 import com.aelitis.azureus.util.DataSourceUtils;
 import com.aelitis.azureus.util.PlayUtils;
-import com.aelitis.azureus.util.PublishUtils;
 import com.aelitis.azureus.util.win32.Win32Utils;
 
 /**
@@ -234,8 +232,6 @@ public class TorrentListViewsUtils
 	public static void playOrStreamDataSource(Object ds,
 			SWTSkinButtonUtility btn, String referal) {
 
-		debugDCAD("enter - playOrStreamDataSource");
-
 		DownloadManager dm = DataSourceUtils.getDM(ds);
 		if (dm == null) {
 			downloadDataSource(ds, true, referal);
@@ -243,8 +239,6 @@ public class TorrentListViewsUtils
 			playOrStream(dm, btn);
 		}
 
-		debugDCAD("exit - playOrStreamDataSource");
-
 	}
 
 	public static void downloadDataSource(Object ds, boolean playNow,
@@ -303,34 +297,29 @@ public class TorrentListViewsUtils
 		}
 	}
 
-	public static boolean playOrStream(final DownloadManager dm,
+	public static void playOrStream(final DownloadManager dm,
 			final SWTSkinButtonUtility btn) {
-		boolean played = _playOrStream(dm, btn);
-		if (played) {
-			PlatformTorrentUtils.setHasBeenOpened(dm, true);
-		}
-		return played;
+		_playOrStream(dm, btn);
 	}
 
-	private static boolean _playOrStream(final DownloadManager dm,
+	private static void _playOrStream(final DownloadManager dm,
 			final SWTSkinButtonUtility btn) {
 
-		debugDCAD("enter - playOrStream");
-
 		if (dm == null) {
-			return false;
+			return;
 		}
 
 		//		if (!canPlay(dm)) {
 		//			return false;
 		//		}
 
-		TOTorrent torrent = dm.getTorrent();
+		final TOTorrent torrent = dm.getTorrent();
 		if (PlayUtils.canUseEMP(torrent)) {
 			debug("Can use EMP");
 
 			if (openInEMP(dm)) {
-				return true;
+				PlatformTorrentUtils.setHasBeenOpened(dm, true);
+				return;
 			} else {
 				debug("Open EMP Failed");
 			}
@@ -347,7 +336,7 @@ public class TorrentListViewsUtils
 		boolean reenableButton = false;
 		try {
 			if (!PlayUtils.canProgressiveOrIsComplete(torrent)) {
-				return false;
+				return;
 			}
 
 			File file;
@@ -358,14 +347,16 @@ public class TorrentListViewsUtils
 			if (edm != null) {
 				boolean doProgressive = edm.getProgressiveMode();
 				if (doProgressive && edm.getProgressivePlayETA() > 0) {
-					return false;
+					return;
 				}
 
 				if (!doProgressive && dm.getDiskManagerFileInfo().length > 1
 						&& PlatformTorrentUtils.getContentPrimaryFileIndex(torrent) == -1) {
 					// multi-file torrent that we aren't progressive playing or useEMPing
 					Utils.launch(dm.getSaveLocation().getAbsolutePath());
-					return true;
+  				reenableButton = true;
+  				PlatformTorrentUtils.setHasBeenOpened(dm, true);
+  				return;
 				}
 
 				file = edm.getPrimaryFile().getFile(true);
@@ -374,6 +365,8 @@ public class TorrentListViewsUtils
 				sFile = dm.getDownloadState().getPrimaryFile();
 				file = new File(sFile);
 			}
+			
+			final String sfFile = sFile;
 
 			String ext = FileUtil.getExtension(sFile);
 			
@@ -381,22 +374,24 @@ public class TorrentListViewsUtils
   			if (ext.equalsIgnoreCase(".exe")
   					&& DataSourceUtils.isPlatformContent(dm)
   					&& "Game".equalsIgnoreCase(PlatformTorrentUtils.getContentType(dm.getTorrent()))) {
+  				reenableButton = true;
   				Utils.launch(sFile);
-  				return true;
+  				PlatformTorrentUtils.setHasBeenOpened(dm, true);
+  				return;
   			}
 			} catch (Exception e) {
 				Debug.out(e);
 			}
 
-			String sPrefix = "v3.mb.openFile.";
+			final String sPrefix = "v3.mb.openFile.";
 			
 
 			UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
 			if (functionsSWT == null) {
-				return false;
+				return;
 			}
 			
-			Program program = Program.findProgram(ext);
+			final Program program = Program.findProgram(ext);
 			String sTextID;
 			String sFileType;
 			if (program == null) {
@@ -414,86 +409,69 @@ public class TorrentListViewsUtils
 			MessageBoxShell mb = null;
 			if(program != null) {
 				buttons[1] = MessageText.getString(sPrefix + "button.play");
-				mb = new MessageBoxShell(functionsSWT.getMainShell(),
-						MessageText.getString(sPrefix + "title"), MessageText.getString(
-								sTextID, new String[] {
+				mb = new MessageBoxShell(MessageText.getString(sPrefix + "title"),
+						MessageText.getString(sTextID, new String[] {
 									dm.getDisplayName(),
 									sFileType,
 									ext
-								}), buttons, 0, sPrefix + ".remember_id", MessageText.getString(sPrefix
-								+ "remember"), false, 0);
+								}), buttons, 0);
+				mb.setRemember(sPrefix + ".remember_id", false, MessageText.getString(sPrefix
+						+ "remember"));
 				mb.setRememberOnlyIfButton(1);
 				mb.setRelatedObject(dm);
 			} else {
-				mb = new MessageBoxShell(functionsSWT.getMainShell(),
-						MessageText.getString(sPrefix + "title"), MessageText.getString(
-								sTextID, new String[] {
-									dm.getDisplayName(),
-									sFileType,
-									ext
-								}), buttons, 0);
+				mb = new MessageBoxShell(MessageText.getString(sPrefix + "title"),
+						MessageText.getString(sTextID, new String[] {
+							dm.getDisplayName(),
+							sFileType,
+							ext
+						}), buttons, 0);
 				mb.setRelatedObject(dm);
 			}
 
-			int i = mb.open();
-			
-			if(i == 0) {
-				String url = MessageText.getString(sPrefix + "guideurl");
-				if(UrlUtils.isURL(url)) {
-					Utils.launch(url);
+			reenableButton = false;
+			mb.open(new UserPrompterResultListener() {
+				public void prompterClosed(int i) {
+					if(i == 0) {
+						String url = MessageText.getString(sPrefix + "guideurl");
+						if(UrlUtils.isURL(url)) {
+							Utils.launch(url);
+							return;
+						}
+					}
+					
+					if (i != 1 || program == null) {
+						return;
+					}
+					
+    			boolean bComplete = dm.isDownloadComplete(false);
+    
+    			if (bComplete) {
+    				if (btn != null) {
+    					btn.setDisabled(false);
+    				}
+    				runFile(dm.getTorrent(), sfFile);
+    			} else {
+    				if (btn != null) {
+    					btn.setDisabled(false);
+    				}
+    				try {
+    					playViaMediaServer(DownloadManagerImpl.getDownloadStatic(dm));
+    				} catch (DownloadException e) {
+    					Debug.out(e);
+    				}
+    			}
 				}
-			}
+			});
 			
-			if (i != 1 || program == null) {
-				return false;
-			}
-			//}
-
-			boolean bComplete = dm.isDownloadComplete(false);
-
-			if (bComplete) {
-				if (PlatformTorrentUtils.isContentAdEnabled(torrent)) {
-					final String sfFile = sFile;
-					debug("calling createASX from ...Tor.Utils.playOrStream, in is complete block.");
-					DCAdManager.getInstance().createASX(dm,
-							new DCAdManager.ASXCreatedListener() {
-								public void asxCreated(File asxFile) {
-									if (btn != null) {
-										btn.setDisabled(false);
-									}
-									runFile(dm.getTorrent(), asxFile.getAbsolutePath());
-								}
-
-								public void asxFailed() {
-									if (btn != null) {
-										btn.setDisabled(false);
-									}
-									runFile(dm.getTorrent(), sfFile);
-								}
-							});
-				} else {
-					reenableButton = true;
-					runFile(dm.getTorrent(), sFile);
-				}
-			} else {
-				reenableButton = true;
-				try {
-					playViaMediaServer(DownloadManagerImpl.getDownloadStatic(dm));
-				} catch (DownloadException e) {
-					Debug.out(e);
-				}
-			}
 		} finally {
 			if (btn != null && reenableButton) {
 				btn.setDisabled(false);
 			}
 		}
-
-		debugDCAD("enter - playOrStream");
-
-		return true;
 	}
 
+
 	/**
 	 * @param string
 	 *
@@ -518,8 +496,6 @@ public class TorrentListViewsUtils
 				Utils.execSWTThread(new AERunnable() {
 
 					public void runSupport() {
-						debugDCAD("enter - runFile - runSupport");
-
 						if (PlayUtils.canUseEMP(torrent)) {
 							Debug.out("Shouldn't call runFile with EMP torrent.");
 						}
@@ -532,7 +508,6 @@ public class TorrentListViewsUtils
 							Utils.launch(runFile);
 						}
 
-						debugDCAD("exit - runFile - runSupport");
 					}
 
 				});
@@ -554,8 +529,6 @@ public class TorrentListViewsUtils
 	 */
 	private static boolean openInEMP(DownloadManager dm) {
 
-		debugDCAD("enter - openInEMP");
-
 		Class epwClass = null;
 		try {
 			// Assumed we have a core, since we are passed a
@@ -603,15 +576,15 @@ public class TorrentListViewsUtils
 	*
 	* @since 3.0.0.7
 	*/
-	private static void handleNoFileExists(DownloadManager dm) {
-		UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
+	private static void handleNoFileExists(final DownloadManager dm) {
+		final UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
 		if (functionsSWT == null) {
 			return;
 		}
 		ManagerUtils.start(dm);
 
 		String sPrefix = "v3.mb.PlayFileNotFound.";
-		MessageBoxShell mb = new MessageBoxShell(functionsSWT.getMainShell(),
+		MessageBoxShell mb = new MessageBoxShell(
 				MessageText.getString(sPrefix + "title"), MessageText.getString(sPrefix
 						+ "text", new String[] {
 					dm.getDisplayName(),
@@ -621,17 +594,20 @@ public class TorrentListViewsUtils
 					MessageText.getString("Button.cancel"),
 				}, 2);
 		mb.setRelatedObject(dm);
-		int i = mb.open();
-
-		if (i == 0) {
-			ManagerUtils.remove(dm, functionsSWT.getMainShell(), true, false);
-		} else if (i == 1) {
-			dm.forceRecheck(new ForceRecheckListener() {
-				public void forceRecheckComplete(DownloadManager dm) {
-					ManagerUtils.start(dm);
+		mb.open(new UserPrompterResultListener() {
+			public void prompterClosed(int i) {
+				if (i == 0) {
+					ManagerUtils.remove(dm, functionsSWT.getMainShell(), true, false);
+				} else if (i == 1) {
+					dm.forceRecheck(new ForceRecheckListener() {
+						public void forceRecheckComplete(DownloadManager dm) {
+							ManagerUtils.start(dm);
+						}
+					});
 				}
-			});
-		}
+			}
+		});
+
 	}
 
 	/**
@@ -639,8 +615,6 @@ public class TorrentListViewsUtils
 	 */
 	private static boolean runInMediaPlayer(String mediaFile) {
 
-		debugDCAD("enter - runInMediaPlayer");
-
 		if (Constants.isWindows) {
 			String wmpEXE = Win32Utils.getWMP();
 			if (new File(wmpEXE).exists()) {
@@ -673,29 +647,11 @@ public class TorrentListViewsUtils
 	 */
 	public static void playViaMediaServer(Download download) {
 
-		debugDCAD("enter - playViaMediaServer");
-
 		try {
 			final DownloadManager dm = ((DownloadImpl) download).getDownload();
 
 			TOTorrent torrent = dm.getTorrent();
-			if (PlatformTorrentUtils.isContentAdEnabled(torrent)) {
-				debug("calling createASX from ...Tor.Utils.playViaMediaServer, in is complete block. dm="
-						+ dm);
-				DCAdManager.getInstance().createASX(dm,
-						new DCAdManager.ASXCreatedListener() {
-							public void asxCreated(File asxFile) {
-								runFile(dm.getTorrent(), asxFile.getAbsolutePath(), true);
-							}
-
-							public void asxFailed() {
-								runFile(dm.getTorrent(), PlayUtils.getContentUrl(dm), true);
-							}
-						});
-			} else {
-				// force to WMP if we aren't using EMP
-				runFile(torrent, PlayUtils.getContentUrl(dm), true);
-			}
+			runFile(torrent, PlayUtils.getContentUrl(dm), true);
 		} catch (Throwable e) {
 			Logger.log(new LogEvent(LogIDs.UI3, "IPC to media server plugin failed",
 					e));
@@ -706,80 +662,98 @@ public class TorrentListViewsUtils
 		if (dms == null) {
 			return;
 		}
-		
-		int doAllAs = -1;
 
+		// confusing code:
+		// for loop goes through erasing published and low noise torrents until
+		// it reaches a normal one.  We then prompt the user, and stop the loop.
+		// When the user finally chooses an option, we act on it.  If the user
+		// chose to act on all, we do immediately all and quit.  
+		// If the user chose an action just for the one torrent, we do that action, 
+		// remove that item from the array (by nulling it), and then call 
+		// removeDownloads again so we can prompt again (or erase more published/low noise torrents)
 		for (int i = 0; i < dms.length; i++) {
 			DownloadManager dm = dms[i];
 			if (dm != null) {
-				if (PublishUtils.isPublished(dm) || dm.getDownloadState().getFlag(
+				if (dm.getDownloadState().getFlag(
 						Download.FLAG_DO_NOT_DELETE_DATA_ON_REMOVE)) {
 					ManagerUtils.remove(dm, null, true, false, null);
 					continue;
 				}
 
-				boolean deleteTorrent = true;
-				boolean deleteData = true;
+			boolean deleteTorrent = true;
+			boolean deleteData = true;
 
 
-				if (!dm.getDownloadState().getFlag(DownloadManagerState.FLAG_LOW_NOISE)) {
-					String path = dm.getSaveLocation().toString();
-
-					String title = MessageText.getString("deletedata.title");
-					String text = MessageText.getString("v3.deleteContent.message",
-							new String[] {
-								dm.getDisplayName()
-							});
-						
-					int result;
-					if (doAllAs < 0) {
-  					MessageBoxShell mb = new MessageBoxShell(Utils.findAnyShell(), title,
-  							text, new String[] {
-  								MessageText.getString("Button.cancel"),
-  								MessageText.getString("Button.deleteContent.fromComputer"),
-  								MessageText.getString("Button.deleteContent.fromLibrary"),
-  							}, 2, null, null, false, 0);
-  					int numLeft = (dms.length - i);
-  					if (numLeft > 1) {
-    					mb.setRememberText(MessageText.getString(
-									"v3.deleteContent.applyToAll", new String[] {
-										"" + numLeft
-									}));
-    					mb.setRememberID("na", false);
-    					mb.setRememberOnlyIfButton(-3);
-  					}
-  					mb.setRelatedObject(dm);
-  					mb.setLeftImage(ImageLoader.getInstance().getImage("image.trash"));
-  
-  					result = mb.open();
-
-  					ImageLoader.getInstance().releaseImage("image.trash");
-						if (numLeft > 1 && mb.isRemembered()) {
-							doAllAs = result;
-						}
-					} else {
-						result = doAllAs;
-					}
+			if (!dm.getDownloadState().getFlag(DownloadManagerState.FLAG_LOW_NOISE)) {
+				String title = MessageText.getString("deletedata.title");
+				String text = MessageText.getString("v3.deleteContent.message",
+						new String[] {
+							dm.getDisplayName()
+						});
+					
+				final MessageBoxShell mb = new MessageBoxShell(title,
+						text, new String[] {
+							MessageText.getString("Button.cancel"),
+							MessageText.getString("Button.deleteContent.fromComputer"),
+							MessageText.getString("Button.deleteContent.fromLibrary"),
+						}, 2);
+				int numLeft = (dms.length - i);
+				if (numLeft > 1) {
+					mb.setRemember("na", false, MessageText.getString(
+							"v3.deleteContent.applyToAll", new String[] {
+								"" + numLeft
+							}));
+					mb.setRememberOnlyIfButton(-3);
+				}
+				mb.setRelatedObject(dm);
+				mb.setLeftImage(ImageLoader.getInstance().getImage("image.trash"));
 
-					if (result == 1 || result == 2) {
-						if (result == 2) {
-							deleteData = false;
-						}
+				final int index = i;
+				mb.open(new UserPrompterResultListener() {
 					
-						ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
-								deleteTorrent, deleteData, null);
-					} else {
-						if (doAllAs >= 0) {
+					public void prompterClosed(int result) {
+						ImageLoader.getInstance().releaseImage("image.trash");
+						
+						if (result == -1) {
+							// user pressed ESC (as opposed to clicked Cancel), cancel whole
+							// list
 							return;
 						}
-						continue;
+						if (mb.isRemembered()) {
+							if (result == 1 || result == 2) {
+								boolean deleteData = result == 2 ? false : true;
+								boolean deleteTorrent = true;
+							
+								for (int i = index; i < dms.length; i++) {
+									DownloadManager dm = dms[i];
+									ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
+											deleteTorrent, deleteData, null);
+								}
+							} //else cancel
+						} else { // not remembered
+							if (result == 1 || result == 2) {
+								boolean deleteData = result == 2 ? false : true;
+								boolean deleteTorrent = true;
+							
+								DownloadManager dm = dms[index];
+								ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
+										deleteTorrent, deleteData, null);
+							}
+							// remove the one we just did and go through loop again
+							dms[index] = null;
+							if (index != dms.length - 1) {
+								removeDownloads(dms);
+							}
+						}
 					}
-				} else {
-					ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
-							deleteTorrent, deleteData, null);
-				}
+				});
+				return;
+			} else {
+				ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
+						deleteTorrent, deleteData, null);
 			}
-		}
+			dms[i] = null;
+		}}
 	}
 
 	public static void removeDownload(final DownloadManager dm,
@@ -789,16 +763,19 @@ public class TorrentListViewsUtils
 
 		AERunnable failure = null;
 		if (tableView != null) {
-			tableView.removeDataSource(dm, true);
+			tableView.removeDataSource(dm);
+			tableView.processDataSourceQueue();
 
 			failure = new AERunnable() {
 				public void runSupport() {
-					tableView.addDataSource(dm, true);
+					tableView.addDataSource(dm);
+					tableView.processDataSourceQueue();
 				}
 			};
 		}
+		final AERunnable ffailure = failure;
 
-		if (PublishUtils.isPublished(dm) || dm.getDownloadState().getFlag(
+		if (dm.getDownloadState().getFlag(
 				Download.FLAG_DO_NOT_DELETE_DATA_ON_REMOVE)) {
 			ManagerUtils.remove(dm, null, true, false, failure);
 			return;
@@ -817,31 +794,37 @@ public class TorrentListViewsUtils
 						dm.getDisplayName()
 					});
 					
-			MessageBoxShell mb = new MessageBoxShell(Utils.findAnyShell(), title,
-					text, new String[] {
+			MessageBoxShell mb = new MessageBoxShell(title, text, new String[] {
 						MessageText.getString("Button.cancel"),
 						MessageText.getString("Button.deleteContent.fromComputer"),
 						MessageText.getString("Button.deleteContent.fromLibrary"),
-					}, 2, null, null, false, 0);
+					}, 2);
 			mb.setRelatedObject(dm);
 			mb.setLeftImage(ImageLoader.getInstance().getImage("image.trash"));
 
-			int result = mb.open();
-			ImageLoader.getInstance().releaseImage("image.trash");
-
-			if (result == 1 || result == 2) {
-				if (result == 2) {
-					deleteData = false;
-				}
-			
-				ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
-						deleteTorrent, deleteData, failure);
-			} else {
-				if (failure != null) {
-					failure.runSupport();
+			mb.open(new UserPrompterResultListener() {
+				
+				public void prompterClosed(int result) {
+					ImageLoader.getInstance().releaseImage("image.trash");
+					
+					boolean deleteData = true;
+					boolean deleteTorrent = true;
+					
+					if (result == 1 || result == 2) {
+						if (result == 2) {
+							deleteData = false;
+						}
+						
+						ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
+								deleteTorrent, deleteData, ffailure);
+					} else {
+						if (ffailure != null) {
+							ffailure.runSupport();
+						}
+						return;
+					}
 				}
-				return;
-			}
+			});
 		} else {
 			ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
 					deleteTorrent, deleteData, failure);
@@ -856,11 +839,7 @@ public class TorrentListViewsUtils
 	public static void showHomeHint(final DownloadManager dm) {
 	}
 
-	public static void debugDCAD(String s) {
-		PlatformDCAdManager.debug("TorrentListViewsUtils: " + s);
-	}//debugDCAD
-
-	public static boolean playOrStream(final DownloadManager dm) {
-		return playOrStream(dm, null);
+	public static void playOrStream(final DownloadManager dm) {
+		playOrStream(dm, null);
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/views/skin/UserAreaUtils.java b/com/aelitis/azureus/ui/swt/views/skin/UserAreaUtils.java
deleted file mode 100644
index 37c142d..0000000
--- a/com/aelitis/azureus/ui/swt/views/skin/UserAreaUtils.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/**
- * Copyright (C) 2007 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package com.aelitis.azureus.ui.swt.views.skin;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.ui.swt.Utils;
-
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.ui.skin.SkinConstants;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.shells.LightBoxBrowserWindow;
-import com.aelitis.azureus.ui.swt.skin.*;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
-import com.aelitis.azureus.ui.swt.utils.SWTLoginUtils;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
-import com.aelitis.azureus.util.*;
-import com.aelitis.azureus.util.LoginInfoManager.LoginInfo;
-
-public class UserAreaUtils
-{
-	private SWTSkin skin;
-
-	private UIFunctionsSWT uiFunctions = null;
-
-	private boolean firstLoginStateSync = true;
-
-	private SWTSkinObjectImage soImage;
-
-	public UserAreaUtils(final SWTSkin skin, UIFunctionsSWT uiFunctions) {
-		this.skin = skin;
-		this.uiFunctions = uiFunctions;
-
-		updateLoginLabels(null);
-		
-		hookListeners();
-		
-	}
-
-	private void hookListeners() {
-
-		/*
-		 * New user-info (drop down arrow)
-		 */
-
-		SWTSkinObject skinObject = skin.getSkinObject("user-info-image");
-		if (skinObject != null) {
-  		final Control control = skinObject.getControl();
-  		final Menu menu = new Menu(control.getShell(), SWT.POP_UP);
-  		fillUserInfoMenu(menu);
-  
-  		menu.addListener(SWT.Show, new Listener() {
-  			public void handleEvent(Event event) {
-  				MenuItem[] menuItems = menu.getItems();
-  				for (int i = 0; i < menuItems.length; i++) {
-  					menuItems[i].dispose();
-  				}
-  
-  				fillUserInfoMenu(menu);
-  			}
-  		});
-
-			SWTSkinButtonUtility btnGo = new SWTSkinButtonUtility(skinObject);
-			btnGo.addSelectionListener(new ButtonListenerAdapter() {
-				public void pressed(SWTSkinButtonUtility buttonUtility, SWTSkinObject skinObject, int stateMask) {
-					Point point = control.getShell().toDisplay(
-							control.getParent().getLocation());
-					point.y += (control.getSize().y / 2) + 10;
-					menu.setLocation(point);
-					menu.setVisible(true);
-				}
-			});
-		}
-
-		/*
-		 * New user-info (name)
-		 */
-		skinObject = skin.getSkinObject("user-info-name");
-
-		if (skinObject != null) {
-			SWTSkinButtonUtility btnGo = new SWTSkinButtonUtility(skinObject);
-			btnGo.addSelectionListener(new ButtonListenerAdapter() {
-				public void pressed(SWTSkinButtonUtility buttonUtility, SWTSkinObject skinObject, int stateMask) {
-					if (true == LoginInfoManager.getInstance().isLoggedIn()) {
-						/*
-						 * If the user is logged in then go to profile page
-						 */
-						if (null != uiFunctions) {
-							String url = ConstantsVuze.getDefaultContentNetwork().getServiceURL( ContentNetwork.SERVICE_MY_PROFILE );
-							uiFunctions.viewURL(url, SkinConstants.VIEWID_BROWSER_BROWSE,
-									"curuser-name");
-						}
-
-					} else {
-						/*
-						 * If the user it not logged in then go to SignIn
-						 */
-
-						SWTLoginUtils.openLoginWindow();
-
-					}
-
-				}
-			});
-		}
-		
-		skinObject = skin.getSkinObject("user-info-profile-image");
-		if (skinObject instanceof SWTSkinObjectImage) {
-			soImage = (SWTSkinObjectImage) skinObject;
-		}
-
-		/*
-		 * Listens for changes in the login state and update the UI appropriately
-		 */
-		LoginInfoManager.getInstance().addListener(new ILoginInfoListener() {
-			public void loginUpdate(LoginInfo info, boolean isNewLoginID) {
-				synchLoginStates(info, isNewLoginID);
-			}
-			
-			// @see com.aelitis.azureus.util.ILoginInfoListener#avatarURLUpdated()
-			public void avatarURLUpdated(String newAvatarURL) {
-				soImage.setImageUrl(newAvatarURL);
-			}
-		});
-	}
-
-	/**
-	 * Updates the login/logout labels and also resets all embedded browsers
-	 * @param userName
-	 * @param displayName
-	 * @param isNewLoginID
-	 */
-	private void synchLoginStates(LoginInfo info, boolean isNewLoginID) {
-
-		updateLoginLabels(info);
-
-		if (firstLoginStateSync) {
-			firstLoginStateSync = false;
-			return;
-		}
-
-		// 3.2 TODO: These are different now that we have a sidebar
-		/*
-		 * Reset browser tabs if the login state has changed
-		 */
-		if (true == isNewLoginID) {
-			/*
-			 * If the user has logged out (user name is null) then reset all pages to their original URL's
-			 */
-			if (null == info.userName) {
-				resetBrowserPage(SkinConstants.VIEWID_BROWSER_BROWSE);
-				resetBrowserPage(SkinConstants.VIEWID_BROWSER_PUBLISH);
-			} else {
-
-				/*
-				 * Otherwise just refresh the current URL so the pages can be re-loaded with fresh information
-				 */
-				refreshBrowserPage(SkinConstants.VIEWID_BROWSER_BROWSE);
-				refreshBrowserPage(SkinConstants.VIEWID_BROWSER_PUBLISH);
-			}
-		}
-	}
-
-	/**
-	 * Updates the login/logout labels to reflect the user's login state
-	 * @param userName
-	 * @param displayName
-	 */
-	private void updateLoginLabels(LoginInfo info) {
-		if (info != null && null != info.userName) {
-			SWTSkinObject skinObjectName = skin.getSkinObject("user-info-name");
-			if (skinObjectName instanceof SWTSkinObjectText) {
-				if (null != info.displayName) {
-					((SWTSkinObjectText) skinObjectName).setText(info.displayName);
-				} else {
-					((SWTSkinObjectText) skinObjectName).setText(info.userName);
-				}
-			}
-
-		} else {
-			SWTSkinObject skinObjectName = skin.getSkinObject("user-info-name");
-			if (skinObjectName instanceof SWTSkinObjectText) {
-				((SWTSkinObjectText) skinObjectName).setTextID("v3.MainWindow.text.log.in");
-			}
-
-		}
-
-		SWTSkinObject skinObject = skin.getSkinObject("user-info");
-		skinObject.relayout();
-	}
-
-	/**
-	 * Resets the embedded browser with the given viewID
-	 * @param targetViewID
-	 */
-	private void resetBrowserPage(String targetViewID) {
-		SWTSkinObject skinObject = skin.getSkinObject(targetViewID);
-		if (skinObject instanceof SWTSkinObjectBrowser) {
-			((SWTSkinObjectBrowser) skinObject).restart();
-		}
-	}
-
-	/**
-	 * Refreshes the embedded browser with the given viewID
-	 * @param targetViewID
-	 */
-	private void refreshBrowserPage(final String targetViewID) {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				final SWTSkinObject skinObject = skin.getSkinObject(targetViewID);
-				if (skinObject instanceof SWTSkinObjectBrowser) {
-					((SWTSkinObjectBrowser) skinObject).getBrowser().refresh();
-				}
-			}
-		});
-	}
-
-	/**
-	 * Fill the menu with the appropriate items for the user info drop down
-	 * @param menu
-	 */
-	private void fillUserInfoMenu(Menu menu) {
-
-		if (true == LoginInfoManager.getInstance().isLoggedIn()) {
-
-			/*
-			 * Account info
-			 */
-			MenuItem item = new MenuItem(menu, SWT.PUSH);
-			item.setText(MessageText.getString("v3.MainWindow.text.my.account"));
-			item.addSelectionListener(new SelectionListener() {
-
-				public void widgetSelected(SelectionEvent e) {
-					if (null != uiFunctions) {
-						String url = ContentNetworkUtils.getUrl(
-								ConstantsVuze.getDefaultContentNetwork(),
-								ContentNetwork.SERVICE_MY_ACCOUNT);
-						if (url == null) {
-							return;
-						}
-						uiFunctions.viewURL(url, SkinConstants.VIEWID_BROWSER_BROWSE,
-								"curuser-account-menu");
-					}
-
-				}
-
-				public void widgetDefaultSelected(SelectionEvent e) {
-					widgetSelected(e);
-				}
-			});
-
-			/*
-			 * Profile
-			 */
-
-			item = new MenuItem(menu, SWT.PUSH);
-			item.setText(MessageText.getString("v3.MainWindow.text.my.profile"));
-			item.addSelectionListener(new SelectionListener() {
-
-				public void widgetSelected(SelectionEvent e) {
-					if (true == LoginInfoManager.getInstance().isLoggedIn()) {
-						/*
-						 * If the user is logged in then go to profile page
-						 */
-						if (null != uiFunctions) {
-							String url = ContentNetworkUtils.getUrl(
-									ConstantsVuze.getDefaultContentNetwork(),
-									ContentNetwork.SERVICE_MY_PROFILE);
-							uiFunctions.viewURL(url, SkinConstants.VIEWID_BROWSER_BROWSE,
-									"curuser-profile-menu");
-						}
-
-					} else {
-						/*
-						 * If the user it not logged in then go to SignIn
-						 */
-
-						SWTLoginUtils.openLoginWindow();
-
-					}
-
-				}
-
-				public void widgetDefaultSelected(SelectionEvent e) {
-					widgetSelected(e);
-				}
-			});
-
-			item = new MenuItem(menu, SWT.SEPARATOR);
-
-			/*
-			 * Logout
-			 */
-			item = new MenuItem(menu, SWT.PUSH);
-			item.setText(MessageText.getString("v3.MainWindow.text.log.out"));
-			item.addSelectionListener(new SelectionListener() {
-
-				public void widgetSelected(SelectionEvent e) {
-					widgetDefaultSelected(e);
-				}
-
-				public void widgetDefaultSelected(SelectionEvent e) {
-
-					/*
-					 * We log out by opening the following URL in a browser.  The page
-					 * that is loaded will send a 'status:login-update' message which the 
-					 * ILoginInfoListener will respond to and update the UI accordingly
-					 */
-					final String url = ContentNetworkUtils.getUrl(
-							ConstantsVuze.getDefaultContentNetwork(),
-							ContentNetwork.SERVICE_LOGOUT);
-					
-					/*
-					 * Loads the page without switching to the On Vuze tab
-					 */
-					SideBarEntrySWT entry = SideBar.getEntry(SkinConstants.VIEWID_BROWSER_BROWSE);
-					if (entry != null && entry.isInTree()) {
-						SWTSkinObjectBrowser soBrowser = SWTSkinUtils.findBrowserSO(entry.getSkinObject());
-						if (soBrowser != null) {
-							soBrowser.setURL(url);
-						} else {
-							uiFunctions.viewURL(url, SkinConstants.VIEWID_BROWSER_BROWSE,
-									"curuser-profile-menu");
-						}
-					}
-
-				}
-			});
-
-		} else {
-
-			LoginInfo info = LoginInfoManager.getInstance().getUserInfo();
-
-			/*
-			 * Account info
-			 */
-			MenuItem item = new MenuItem(menu, SWT.PUSH);
-			item.setText(MessageText.getString("v3.MainWindow.text.my.account"));
-			item.setEnabled(false);
-
-			/*
-			 * Profile
-			 */
-
-			item = new MenuItem(menu, SWT.PUSH);
-			item.setText(MessageText.getString("v3.MainWindow.text.my.profile"));
-			item.setEnabled(false);
-
-			/*
-			 * Sign Up -- Only show if this client instance has not been registered already
-			 */
-			if (true == info.isRegistrationStillOpen) {
-				item = new MenuItem(menu, SWT.SEPARATOR);
-
-				item = new MenuItem(menu, SWT.PUSH);
-				item.setText(MessageText.getString("v3.MainWindow.text.get.started"));
-				item.addSelectionListener(new SelectionListener() {
-
-					public void widgetSelected(SelectionEvent e) {
-						if (null != uiFunctions) {
-							String url = ContentNetworkUtils.getUrl(
-									ConstantsVuze.getDefaultContentNetwork(),
-									ContentNetwork.SERVICE_REGISTER);
-							if (url == null) {
-								return;
-							}
-							new LightBoxBrowserWindow(url, ConstantsVuze.URL_PAGE_VERIFIER_VALUE,
-									460, 577);
-						}
-
-					}
-
-					public void widgetDefaultSelected(SelectionEvent e) {
-						widgetSelected(e);
-					}
-				});
-			}
-		}
-
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/VuzeShareUtils.java b/com/aelitis/azureus/ui/swt/views/skin/VuzeShareUtils.java
deleted file mode 100644
index 9ae06ad..0000000
--- a/com/aelitis/azureus/ui/swt/views/skin/VuzeShareUtils.java
+++ /dev/null
@@ -1,365 +0,0 @@
-package com.aelitis.azureus.ui.swt.views.skin;
-
-import java.util.GregorianCalendar;
-
-import org.eclipse.swt.SWT;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.ui.swt.Utils;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.buddy.VuzeShareable;
-import com.aelitis.azureus.buddy.impl.VuzeBuddyManager;
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
-import com.aelitis.azureus.core.cnetwork.impl.ContentNetworkVuze;
-import com.aelitis.azureus.core.messenger.config.PlatformBuddyMessenger;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfo;
-import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
-import com.aelitis.azureus.ui.selectedcontent.ISelectedVuzeFileContent;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContent;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentV3;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.buddy.VuzeBuddySWT;
-import com.aelitis.azureus.ui.swt.shells.friends.SharePage;
-import com.aelitis.azureus.ui.swt.shells.friends.ShareWizard;
-import com.aelitis.azureus.ui.swt.utils.SWTLoginUtils;
-import com.aelitis.azureus.util.DataSourceUtils;
-
-public class VuzeShareUtils
-{
-	private long DATE_CANSHARENONVUZECN = new GregorianCalendar(2009, 2, 14).getTimeInMillis();
-
-	private static VuzeShareUtils instance;
-
-	public static VuzeShareUtils getInstance() {
-		if (null == instance) {
-			instance = new VuzeShareUtils();
-		}
-		return instance;
-	}
-
-		/**
-		 * Used by EMP
-		 * @deprecated
-		 * @param content
-		 * @param referer
-		 */
-	
-	public void 
-	shareTorrent(
-		ISelectedContent content, String referer) 
-	{
-		shareContent( content, null, referer );
-	}
-	
-	public void
-	shareContent(
-		ISelectedContent 	content, 
-		final VuzeBuddy[] defaultSelectedBuddies,
-		String 				referer )
-	{
-		if (content instanceof SelectedContentV3) {
-			SelectedContentV3 sc = (SelectedContentV3) content;
-			shareContent(sc, defaultSelectedBuddies, referer);
-		} else if (content instanceof SelectedContent) {
-			SelectedContent sc = (SelectedContent) content;
-			shareContent(new SelectedContentV3(sc), defaultSelectedBuddies, referer);
-		}else if ( content instanceof ISelectedVuzeFileContent ){
-			
-			shareVuzeFile((ISelectedVuzeFileContent)content, defaultSelectedBuddies, referer );
-			
-		}else{
-			
-			Debug.out( "No share method defined for " + content );
-		}
-	}
-
-	public void 
-	shareContent(
-		final SelectedContentV3 	content,
-		final VuzeBuddy[] defaultSelectedBuddies,
-		final String 				referer ) 
-	{
-		
-		final DownloadManager dm = content.getDownloadManager();
-		
-		if (!canShare(content)) {
-			Debug.out("Tried to share " + content.getHash()
-					+ " but not shareable");
-			return;
-		}
-
-		PlatformBuddyMessenger.startShare(referer,
-				content.isPlatformContent() ? content.getHash() : null);
-
-		if (!VuzeBuddyManager.isEnabled()) {
-			VuzeBuddyManager.showDisabledDialog();
-			return;
-		}
-
-			//TODO : Gudy : make sure that this private detection method is reliable enough
-		
-		if ( dm != null	&& (TorrentUtils.isReallyPrivate(content.getTorrent()))) {
-			Utils.openMessageBox(Utils.findAnyShell(), SWT.OK, "v3.share.private",
-					(String[]) null);
-			return;
-		}
-
-
-		VuzeShareable	shareable = 
-			new	VuzeShareable()
-			{
-				public String
-				getHash()
-				{
-					return( content.getHash());
-				}
-				
-				public String
-				getDisplayName()
-				{
-					return( content.getDisplayName());
-				}
-				
-				public String
-				getThumbURL()
-				{
-					return( content.getThumbURL());
-				}
-				
-				public boolean
-				isPlatformContent()
-				{
-					return( content.isPlatformContent());
-				}
-				
-				public String 
-				getPublisher() 
-				{
-					if ( dm == null ){
-						
-						return( null );
-					}
-					
-					return( PlatformTorrentUtils.getContentPublisher(dm.getTorrent()));
-				}
-				
-				public long 
-				getSize() 
-				{
-					if ( dm == null ){
-						
-						return( 0 );
-					}
-					
-					return( dm.getSize());
-				}
-				
-				public byte[]
-				getImageBytes()
-				{
-					return( content.getImageBytes());
-				}
-				
-				public boolean
-				canPlay()
-				{
-					return( content.canPlay());
-				}
-				
-				public TOTorrent 
-				getTorrent() 
-				{
-					return(content.getTorrent());
-				}
-				
-				public DownloadManager 
-				getDownloadManager() 
-				{
-					return( content.getDownloadManager());
-				}
-				
-				public DownloadUrlInfo 
-				getDownloadInfo() 
-				{
-					return( content.getDownloadInfo());
-				}
-			};
-
-		doShare( shareable, defaultSelectedBuddies, referer );
-	}
-	
-	public void 
-	shareVuzeFile(
-		final ISelectedVuzeFileContent 		content,
-		final VuzeBuddy[] defaultSelectedBuddies,
-		final String 						referer ) 
-	{
-		
-		PlatformBuddyMessenger.startShare( referer, null );
-
-		if (!VuzeBuddyManager.isEnabled()){
-			
-			VuzeBuddyManager.showDisabledDialog();
-			
-			return;
-		}
-
-		VuzeShareable	shareable = 
-			new	VuzeShareable()
-			{
-				public String
-				getHash()
-				{
-					return( content.getHash());
-				}
-				
-				public String
-				getDisplayName()
-				{
-					return( content.getDisplayName());
-				}
-				
-				public String
-				getThumbURL()
-				{
-					return( null );
-				}
-				
-				public boolean
-				isPlatformContent()
-				{
-					return( false );
-				}
-				
-				public String 
-				getPublisher() 
-				{
-					return( null );
-				}
-				
-				public long 
-				getSize() 
-				{
-					return( 0 );
-				}
-				
-				public byte[]
-				getImageBytes()
-				{
-					return( null );
-				}
-				
-				public boolean
-				canPlay()
-				{
-					return( false );
-				}
-				
-				public TOTorrent 
-				getTorrent() 
-				{
-					return( content.getTorrent());
-				}
-				
-				public DownloadManager 
-				getDownloadManager() 
-				{
-					return( null );
-				}
-				
-				public DownloadUrlInfo 
-				getDownloadInfo() 
-				{
-					return( null );
-				}
-			};
-
-		doShare( shareable, defaultSelectedBuddies, referer );
-	}
-	
-	protected void
-	doShare(
-		final VuzeShareable	shareable,
-		final VuzeBuddy[] defaultSelectedBuddies,
-		final String		referer )
-	{
-		SWTLoginUtils.waitForLogin(new SWTLoginUtils.loginWaitListener() {
-			public void loginComplete() {
-				try {
-					//sharePage.setShareItem(currentContent, referer);
-
-					ShareWizard wizard = new ShareWizard(
-							UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell(),
-							SWT.DIALOG_TRIM | SWT.RESIZE);
-					wizard.setText("Vuze - Wizard");
-					wizard.setSize(500, 550);
-
-					SharePage newSharePage = (SharePage) wizard.getPage( SharePage.ID );
-				
-					newSharePage.setShareItem( shareable, referer );
-					
-					/*
-					 * Opens a centered free-floating shell
-					 */
-
-					UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-					
-					if (null == uiFunctions) {
-						/*
-						 * Centers on the active monitor
-						 */
-						Utils.centreWindow(wizard.getShell());
-					} else {
-						/*
-						 * Centers on the main application window
-						 */
-						Utils.centerWindowRelativeTo(wizard.getShell(),
-								uiFunctions.getMainShell());
-					}
-
-					wizard.open();
-
-					if (defaultSelectedBuddies != null) {
-						for (VuzeBuddy vuzeBuddy : defaultSelectedBuddies) {
-							if (vuzeBuddy instanceof VuzeBuddySWT) {
-								newSharePage.addBuddy((VuzeBuddySWT) vuzeBuddy);
-							}
-						}
-					}
-
-
-				} catch (Throwable e) {
-					Debug.printStackTrace(e);
-				}
-			}
-		});
-	}
-
-	public boolean canShare(Object datasource) {
-		TOTorrent torrent = DataSourceUtils.getTorrent(datasource);
-		if (torrent == null) {
-			if (DataSourceUtils.getHash(datasource) != null) {
-				return true;
-			}
-			return false;
-		}
-		
-		long id = PlatformTorrentUtils.getContentNetworkID(torrent);
-		if (id == ContentNetwork.CONTENT_NETWORK_UNKNOWN) {
-			return true;
-		}
-		if (SystemTime.getCurrentTime() >= DATE_CANSHARENONVUZECN) {
-			return true;
-		}
-		ContentNetwork cn = ContentNetworkManagerFactory.getSingleton().getContentNetwork(
-				id);
-		return cn == null || cn.getID() == ContentNetworkVuze.CONTENT_NETWORK_VUZE;
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/WelcomeView.java b/com/aelitis/azureus/ui/swt/views/skin/WelcomeView.java
index c522c65..2d1e29b 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/WelcomeView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/WelcomeView.java
@@ -23,7 +23,6 @@ package com.aelitis.azureus.ui.swt.views.skin;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
 import com.aelitis.azureus.ui.skin.SkinConstants;
 import com.aelitis.azureus.ui.swt.browser.BrowserContext.loadingListener;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
@@ -76,15 +75,7 @@ public class WelcomeView
 			public void sidebarClosed(SideBarEntry entry) {
 				SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
 				if (sidebar != null) {
-					String startTab;
-					if (COConfigurationManager.getBooleanParameter("v3.Start Advanced")) {
-						startTab = SideBar.SIDEBAR_SECTION_LIBRARY;
-					} else {
-						ContentNetwork startupCN = ContentNetworkManagerFactory.getSingleton().getStartupContentNetwork();
-						startTab = "ContentNetwork." + startupCN.getID();
-					}
-
-					sidebar.showEntryByID(startTab);
+					sidebar.showEntryByID(SideBar.SIDEBAR_SECTION_LIBRARY);
 				}
 			}
 		});
diff --git a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBar.java b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBar.java
index b537576..4054c61 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBar.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBar.java
@@ -62,6 +62,7 @@ import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewEventCancelledException;
 import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
 import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT.TriggerInThread;
 import org.gudy.azureus2.ui.swt.views.*;
 import org.gudy.azureus2.ui.swt.views.stats.StatsView;
@@ -112,6 +113,14 @@ public class SideBar
 	implements UIUpdatable, ViewTitleInfoListener
 {
 	private static final boolean END_INDENT = Constants.isLinux || Constants.isWindows2000 || Constants.isWindows9598ME;
+	
+	private static final boolean USE_PAINTITEM = Utils.isCocoa;
+	
+	// Need to use paint even on Cocoa, because there's cases where an area
+	// will become invalidated and we don't get a paintitem :(
+	private static final boolean USE_PAINT = true;
+	
+	private static final boolean HIDE_NATIVE_EXPANDER = false;
 
 	private static final int SIDEBAR_SPACING = 2;
 
@@ -131,8 +140,6 @@ public class SideBar
 
 	public static final String SIDEBAR_SECTION_WELCOME = "Welcome";
 
-	public static final String SIDEBAR_SECTION_PUBLISH = "Publish";
-
 	public static final String SIDEBAR_SECTION_SUBSCRIPTIONS = "Subscriptions";
 
 	public static final String SIDEBAR_SECTION_DEVICES = "Devices";
@@ -153,7 +160,7 @@ public class SideBar
 
 	private static final int IMAGELEFT_GAP = 5;
 
-	private static final boolean ALWAYS_IMAGE_GAP = false;
+	private static final boolean ALWAYS_IMAGE_GAP = true;
 
 	private static final String[] default_indicator_colors = {
 		"#000000",
@@ -162,6 +169,8 @@ public class SideBar
 		"#1c2056"
 	};
 
+	private static final boolean DO_OUR_OWN_TREE_INDENT = Utils.isCocoa;
+
 	private SWTSkin skin;
 
 	private SWTSkinObject soSideBarContents;
@@ -587,16 +596,53 @@ public class SideBar
 						break;
 					}
 					case SWT.PaintItem: {
-						//paintSideBar(event);
+						if (USE_PAINTITEM) {
+							String id = (String) ((TreeItem) event.item).getData("Plugin.viewID");
+							//System.out.println(event.item + ";" + event.index + ";" + event.detail + ";" + id);
+							SideBarEntrySWT entry = getEntry(id);
+							paintSideBar(event, entry);
+						}
 						break;
 					}
 
 					case SWT.Paint: {
-						//System.out.println("Paint: " + event.getBounds() + ";" + event.detail + ";" + event.index);
+						if (HIDE_NATIVE_EXPANDER) {
+							boolean selected = (event.detail & SWT.SELECTED) > 0;
+							Rectangle bounds = event.getBounds();
+							int indent = END_INDENT ? tree.getClientArea().width - 1 : 0;
+							int y = event.y + 1;
+							treeItem = tree.getItem(new Point(indent, y));
+
+							while (treeItem != null) {
+								String id = (String) treeItem.getData("Plugin.viewID");
+								SideBarEntrySWT entry = getEntry(id);
+								Rectangle itemBounds = entry.getBounds();
+
+								if (itemBounds != null && entry.disableCollapse) {
+									Rectangle paintArea = treeItem.getBounds();
+									paintArea.x = 0;
+									paintArea.width = 17;
+									selected = tree.getSelectionCount() == 1
+											&& tree.getSelection()[0].equals(treeItem);
+									paintEntryBG(selected, event.gc, paintArea, entry);
+									y = itemBounds.y + itemBounds.height + 1;
+  							} else {
+  								y += tree.getItemHeight();
+  							}
+  
+  							if (y > bounds.y + bounds.height) {
+  								break;
+  							}
+  							treeItem = tree.getItem(new Point(indent, y));
+							}
+						}
+
+						
+						//System.out.println("Paint: " + event.getBounds() + ";" + event.detail + ";" + event.index + ";" + event.gc.getClipping() + "  " + Debug.getCompressedStackTrace());
+						if (!USE_PAINT) {
+							return;
+						}
 						Rectangle bounds = event.getBounds();
-						//if (tree.getItemCount() == 0) {
-						//	return;
-						//}
 						int indent = END_INDENT ? tree.getClientArea().width - 1 : 0;
 						int y = event.y + 1;
 						treeItem = tree.getItem(new Point(indent, y));
@@ -618,7 +664,7 @@ public class SideBar
   							Rectangle newClip = bounds.intersection(itemBounds);
   							//System.out.println("Paint " + id + " @ " + newClip);
   							event.setBounds(newClip);
-  							//event.gc.setClipping(newClip);
+  							event.gc.setClipping(newClip);
   
   							paintSideBar(event, entry);
 
@@ -646,7 +692,7 @@ public class SideBar
 					case SWT.EraseItem: {
 						//event.detail &= ~SWT.FOREGROUND;
 						//event.detail &= ~(SWT.FOREGROUND | SWT.BACKGROUND);
-						event.doit = false;
+						event.doit = true;
 						break;
 					}
 
@@ -739,8 +785,10 @@ public class SideBar
 		tree.addListener(SWT.MeasureItem, treeListener);
 		tree.addListener(SWT.Resize, treeListener);
 		tree.addListener(SWT.Paint, treeListener);
-		//tree.addListener(SWT.PaintItem, treeListener);
-		//tree.addListener(SWT.EraseItem, treeListener);
+		if (USE_PAINTITEM) {
+			tree.addListener(SWT.PaintItem, treeListener);
+			tree.addListener(SWT.EraseItem, treeListener);
+		}
 
 		tree.addListener(SWT.Selection, treeListener);
 		tree.addListener(SWT.Dispose, treeListener);
@@ -1020,32 +1068,12 @@ public class SideBar
 			}
 		}
 	}
-
-	/**
-	 * @param event
-	 * @param sideBarEntry
-	 *
-	 * @since 3.1.0.1
-	 */
-	protected void paintSideBar(Event event, SideBarEntrySWT sideBarEntry) {
-		TreeItem treeItem = (TreeItem) event.item;
-		Rectangle itemBounds = treeItem.getBounds();
-
-		String text = (String) treeItem.getData("text");
-		if (text == null)
-			text = "";
-
-		//Point size = event.gc.textExtent(text);
-		//Rectangle treeBounds = tree.getBounds();
-		GC gc = event.gc;
-
-		gc.setAntialias(SWT.ON);
-		gc.setAdvanced(true);
-		//gc.setClipping((Rectangle) null);
-
-		boolean selected = (event.detail & SWT.SELECTED) > 0;
+	
+	private Color paintEntryBG(boolean selected, GC gc, Rectangle drawBounds, SideBarEntrySWT sideBarEntry) {
 		Color fgText = Colors.black;
 		if (selected) {
+			//System.out.println("gmmm" + drawBounds + ": " + Debug.getCompressedStackTrace());
+			gc.setClipping((Rectangle)null);
 			if (fgSel != null) {
 				fgText = fgSel;
 			}
@@ -1063,12 +1091,13 @@ public class SideBar
 			}
 
 			gc.setBackground(color1);
-			gc.fillRectangle(event.x, itemBounds.y, event.width, 3);
+			gc.fillRectangle(drawBounds.x, drawBounds.y, drawBounds.width, 3);
 
 			gc.setForeground(color1);
 			gc.setBackground(color2);
-			gc.fillGradientRectangle(event.x, itemBounds.y + 3, event.width,
-					itemBounds.height - 3, true);
+			//System.out.println("FOO");
+			//gc.fillGradientRectangle(itemBounds.x, itemBounds.y, itemBounds.width, itemBounds.height, true);
+			gc.fillGradientRectangle(drawBounds.x, drawBounds.y + 3, drawBounds.width,	drawBounds.height - 3, true);
 		} else {
 
 			if (fg != null) {
@@ -1082,8 +1111,36 @@ public class SideBar
 				gc.setBackground(ColorCache.getColor(gc.getDevice(), "#2688aa"));
 			}
 			
-			gc.fillRectangle(event.getBounds());
+			gc.fillRectangle(drawBounds);
 		}
+		return fgText;
+	}
+
+	/**
+	 * @param event
+	 * @param sideBarEntry
+	 *
+	 * @since 3.1.0.1
+	 */
+	protected void paintSideBar(Event event, SideBarEntrySWT sideBarEntry) {
+		TreeItem treeItem = (TreeItem) event.item;
+		Rectangle itemBounds = treeItem.getBounds();
+		Rectangle drawBounds = Utils.isCocoa ? event.gc.getClipping() : event.getBounds();
+		
+		String text = (String) treeItem.getData("text");
+		if (text == null)
+			text = "";
+
+		//Point size = event.gc.textExtent(text);
+		//Rectangle treeBounds = tree.getBounds();
+		GC gc = event.gc;
+
+		gc.setAntialias(SWT.ON);
+		gc.setAdvanced(true);
+		//gc.setClipping((Rectangle) null);
+
+		boolean selected = (event.detail & SWT.SELECTED) > 0;
+		Color fgText = paintEntryBG(selected, gc, drawBounds, sideBarEntry);
 
 		Rectangle treeArea = tree.getClientArea();
 
@@ -1093,6 +1150,15 @@ public class SideBar
 			String id = (String) treeItem.getData("Plugin.viewID");
 			sideBarEntry = getEntry(id);
 		}
+		if (DO_OUR_OWN_TREE_INDENT) {
+			int indentLevel = 0;
+			TreeItem tempItem = treeItem;
+			while (tempItem != null)  {
+				tempItem =  tempItem.getParentItem();
+				indentLevel++;
+			}
+			itemBounds.x += (18 * indentLevel);
+		}
 		int x1IndicatorOfs = SIDEBAR_SPACING;
 		int x0IndicatorOfs = itemBounds.x;
 
@@ -1267,7 +1333,8 @@ public class SideBar
 		Rectangle clipping = new Rectangle(x0IndicatorOfs, itemBounds.y,
 				treeArea.width - x1IndicatorOfs - SIDEBAR_SPACING - x0IndicatorOfs,
 				itemBounds.height);
-		if (event.getBounds().intersects(clipping)) {
+		//System.out.println("itemBounds=" + itemBounds + ";event=" + event.getBounds() + ";" + event.gc.getClipping() + ";" + text);
+		if (drawBounds.intersects(clipping)) {
 			//gc.setClipping(clipping);
 
 			if (text.startsWith(" ")) {
@@ -1276,6 +1343,8 @@ public class SideBar
 				clipping.width -= 30;
 			}
 
+			//System.out.println("draw at " + clipping + " " + text);
+
 			GCStringPrinter sp = new GCStringPrinter(gc, text, clipping, true, false, SWT.NONE);
 			sp.printString();
 			clipping.x += sp.getCalculatedSize().x + 5;
@@ -1307,12 +1376,15 @@ public class SideBar
 
 		// OSX overrides the twisty, and we can't use the default twisty
 		// on Windows because it doesn't have transparency and looks ugly
-		if (treeItem.getItemCount() > 0 && !sideBarEntry.disableCollapse) {
+		if (treeItem.getItemCount() > 0 && !sideBarEntry.disableCollapse && (!Utils.isCocoa || !HIDE_NATIVE_EXPANDER)) {
 			gc.setAntialias(SWT.ON);
 			Color oldBG = gc.getBackground();
 			gc.setBackground(gc.getForeground());
 			if (treeItem.getExpanded()) {
 				int xStart = 15;
+				if (Utils.isCocoa) {
+					xStart -= 5;
+				}
 				int arrowSize = 8;
 				int yStart = itemBounds.height - (itemBounds.height + arrowSize) / 2;
 				gc.fillPolygon(new int[] {
@@ -1325,6 +1397,9 @@ public class SideBar
 				});
 			} else {
 				int xStart = 15;
+				if (Utils.isCocoa) {
+					xStart -= 5;
+				}
 				int arrowSize = 8;
 				int yStart = itemBounds.height - (itemBounds.height + arrowSize) / 2;
 				gc.fillPolygon(new int[] {
@@ -1633,7 +1708,7 @@ public class SideBar
 						s += "\n";
 					}
 				}
-				Utils.openMessageBox(null, SWT.OK, "test", s);
+				new MessageBoxShell(SWT.OK, "test", s).open(null);
 			}
 		});
 
@@ -1756,12 +1831,19 @@ public class SideBar
 		}
 
 		if (parentTreeItem instanceof Tree) {
+			Tree tree = (Tree) parentTreeItem;
+			if (tree.isDisposed()) {
+				return null;
+			}
 			if (index >= 0) {
-				treeItem = new TreeItem((Tree) parentTreeItem, SWT.NONE, index);
+				treeItem = new TreeItem(tree, SWT.NONE, index);
 			} else {
-				treeItem = new TreeItem((Tree) parentTreeItem, SWT.NONE);
+				treeItem = new TreeItem(tree, SWT.NONE);
 			}
 		} else {
+			if (((TreeItem) parentTreeItem).isDisposed()) {
+				return null;
+			}
 			if (index >= 0) {
 				treeItem = new TreeItem((TreeItem) parentTreeItem, SWT.NONE, index);
 			} else {
@@ -1961,6 +2043,9 @@ public class SideBar
 	}
 
 	private void _itemSelected(TreeItem treeItem) {
+		if (treeItem == null) {
+			return;
+		}
 		TreeItem[] selection = tree.getSelection();
 		if (selection == null || selection.length == 0 || selection[0] != treeItem) {
 			tree.showItem(treeItem);
@@ -2083,6 +2168,14 @@ public class SideBar
 			c.setVisible(true);
 		}
 
+		if (currentSideBarEntry.iview instanceof IViewExtension) {
+			try {
+				((IViewExtension)currentSideBarEntry.iview).viewActivated();
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+
 		// hide old
 		if (oldEntry != null && oldEntry != newSideBarInfo) {
 			if (lastImage != null && !lastImage.isDisposed()) {
@@ -2109,6 +2202,14 @@ public class SideBar
 					oldComposite.setVisible(false);
 					oldComposite.getShell().update();
 				}
+				
+				if (oldEntry.iview instanceof IViewExtension) {
+					try {
+						((IViewExtension)oldEntry.iview).viewDeactivated();
+					} catch (Exception e) {
+						Debug.out(e);
+					}
+				}
 			}
 		}
 
@@ -2793,12 +2894,6 @@ public class SideBar
 			SideBarEntrySWT entryWelcome = createWelcomeSection();
 			itemSelected(entryWelcome.treeItem);
 			return true;
-		} else if (id.equals(SIDEBAR_SECTION_PUBLISH)) {
-			SideBarEntrySWT entryPublish = createEntryFromSkinRef(
-					SIDEBAR_SECTION_BROWSE, SIDEBAR_SECTION_PUBLISH, "publishtab.area",
-					"Publish", null, null, true, -1);
-			itemSelected(entryPublish.treeItem);
-			return true;
 		} else if (id.startsWith("ContentNetwork.")) {
 			long networkID = Long.parseLong(id.substring(15));
 			handleContentNetworkSwitch(id, networkID);
@@ -2827,8 +2922,6 @@ public class SideBar
 			id = tabID;
 		} else if (tabID.equals("library") || tabID.equals("minilibrary")) {
 			id = SIDEBAR_SECTION_LIBRARY;
-		} else if (tabID.equals("publish")) {
-			id = SIDEBAR_SECTION_PUBLISH;
 		} else if (tabID.equals("activities")) {
 			id = SIDEBAR_SECTION_ACTIVITIES;
 		} else if (tabID.startsWith("ContentNetwork.")) {
diff --git a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarEntrySWT.java b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarEntrySWT.java
index 43c8337..0a06210 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarEntrySWT.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarEntrySWT.java
@@ -268,7 +268,7 @@ public class SideBarEntrySWT implements SideBarEntry
 				Rectangle bounds = treeItem.getBounds();
 				Rectangle treeBounds = tree.getBounds();
 				tree.redraw(0, bounds.y, treeBounds.width, bounds.height, true);
-				tree.update();
+				//tree.update();
 			}
 		});
 	}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarVitalityImageSWT.java b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarVitalityImageSWT.java
index dfa5371..cfbbc5d 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarVitalityImageSWT.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarVitalityImageSWT.java
@@ -123,8 +123,9 @@ public class SideBarVitalityImageSWT
 									return;
 								}
 								Tree parent = treeItem.getParent();
-								parent.redraw(hitArea.x, hitArea.y, hitArea.width, hitArea.height,
-										false);
+								// SWT.PAINTITEM won't fire on Cocoa unless whole row is dirtied
+								Rectangle redrawBounds = Utils.isCocoa ? treeItem.getBounds() : hitArea;
+								parent.redraw(redrawBounds.x, redrawBounds.y, redrawBounds.width, redrawBounds.height,	true);
 								parent.update();
 							}
 						});
diff --git a/com/aelitis/azureus/ui/swt/views/skin/widgets/FriendsList.java b/com/aelitis/azureus/ui/swt/views/skin/widgets/FriendsList.java
deleted file mode 100644
index 0caabf0..0000000
--- a/com/aelitis/azureus/ui/swt/views/skin/widgets/FriendsList.java
+++ /dev/null
@@ -1,547 +0,0 @@
-package com.aelitis.azureus.ui.swt.views.skin.widgets;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ControlListener;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.events.MouseTrackAdapter;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
-
-import com.aelitis.azureus.buddy.VuzeBuddy;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinFactory;
-import com.aelitis.azureus.ui.swt.views.skin.BuddiesViewer;
-
-public class FriendsList
-{
-
-	private Composite content;
-
-	private ScrolledComposite scrollable;
-
-	private Canvas canvas;
-
-	private List friendsWidgets = new ArrayList();
-
-	private Color widgetBackgroundColor;
-
-	private Color borderColor;
-//
-//	private Color normalColor;
-
-	private boolean isEmailDisplayOnly = false;
-
-	private BuddiesViewer buddiesViewer;
-
-	private Image default_prompt_image = null;
-
-	private String default_prompt_text = null;
-
-	private Rectangle textBounds;
-
-//	private Color textColor;
-
-	public FriendsList(Composite parent) {
-		content = new Composite(parent, SWT.NONE);
-		FillLayout fLayout = new FillLayout();
-		fLayout.marginHeight = 4;
-		fLayout.marginWidth = 4;
-		content.setLayout(fLayout);
-		content.setBackgroundMode(SWT.INHERIT_DEFAULT);
-
-		scrollable = new ScrolledComposite(content, SWT.V_SCROLL | SWT.NONE);
-		scrollable.setExpandHorizontal(true);
-		scrollable.setExpandVertical(true);
-		scrollable.setBackgroundMode(SWT.INHERIT_DEFAULT);
-
-		canvas = new Canvas(scrollable, SWT.DOUBLE_BUFFERED);
-		borderColor = SWTSkinFactory.getInstance().getSkinProperties().getColor(
-				"color.widget.border");
-//		normalColor = SWTSkinFactory.getInstance().getSkinProperties().getColor(
-//				"color.table.bg");
-//		textColor = SWTSkinFactory.getInstance().getSkinProperties().getColor(
-//				"color.text.fg");
-//
-//		widgetBackgroundColor = SWTSkinFactory.getInstance().getSkinProperties().getColor(
-//				"color.widget.container.bg");
-		widgetBackgroundColor = parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
-		scrollable.setContent(canvas);
-
-		init();
-	}
-
-	private void init() {
-
-		canvas.addPaintListener(new PaintListener() {
-
-			public void paintControl(PaintEvent e) {
-				textBounds = canvas.getClientArea();
-
-				try {
-					e.gc.setAntialias(SWT.ON);
-					e.gc.setTextAntialias(SWT.ON);
-					e.gc.setInterpolation(SWT.HIGH);
-				} catch (Exception ex) {
-					// ignore.. some of these may not be avail
-				}
-
-				Rectangle bounds = canvas.getBounds();
-				bounds.width -= 1;
-				bounds.height -= 1;
-//				if (normalColor != null) {
-//					e.gc.setBackground(normalColor);
-//				}
-				e.gc.fillRectangle(bounds);
-				if (borderColor != null) {
-					e.gc.setForeground(borderColor);
-					e.gc.drawRectangle(bounds);
-				}
-
-				if (friendsWidgets.size() < 1) {
-//					if (textColor != null) {
-//						e.gc.setForeground(textColor);
-//					}
-//					int imageXOffset = 16;
-//					if (null != default_prompt_image
-//							&& false == default_prompt_image.isDisposed()) {
-//						Rectangle imageBounds = default_prompt_image.getBounds();
-//						e.gc.drawImage(default_prompt_image, imageXOffset,
-//								(bounds.height / 2) - (imageBounds.height / 2));
-//
-//						textBounds.x += default_prompt_image.getBounds().width
-//								+ imageXOffset + 8;
-//						textBounds.width -= default_prompt_image.getBounds().width
-//								+ imageXOffset + 8;
-//					}
-
-					textBounds.x += 8;
-					textBounds.width -= 16;
-					
-					if (null != default_prompt_text && default_prompt_text.length() > 0) {
-						GCStringPrinter.printString(e.gc, default_prompt_text, textBounds,
-								false, false, SWT.WRAP | SWT.CENTER);
-					}
-				}
-			}
-		});
-
-		canvas.addControlListener(new ControlListener() {
-
-			public void controlResized(ControlEvent e) {
-				Rectangle r = scrollable.getClientArea();
-				scrollable.setMinSize(canvas.computeSize(r.width, SWT.DEFAULT));
-			}
-
-			public void controlMoved(ControlEvent e) {
-				// TODO Auto-generated method stub
-
-			}
-		});
-
-		canvas.setBackground(widgetBackgroundColor);
-
-		GridLayout gLayout = new GridLayout();
-		gLayout.marginWidth = 1;
-		gLayout.marginHeight = 1;
-		gLayout.verticalSpacing = 0;
-		gLayout.horizontalSpacing = 0;
-
-		canvas.setLayout(gLayout);
-
-		content.layout(true, true);
-	}
-
-	public void addFriend(final VuzeBuddy buddy) {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				if (null == findWidget(buddy)) {
-					FriendWidget widget = new FriendWidget(canvas, buddy);
-					Rectangle r = scrollable.getClientArea();
-
-					friendsWidgets.add(widget);
-					GridData gData = new GridData(GridData.FILL_HORIZONTAL);
-					gData.heightHint = 22;
-					widget.getControl().setLayoutData(gData);
-					canvas.layout(true, true);
-					scrollable.setMinSize(canvas.computeSize(r.width, SWT.DEFAULT));
-					content.layout(true, true);
-					canvas.redraw();
-				}
-			}
-		});
-	}
-
-	public void removeFriend(final VuzeBuddy buddy) {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				FriendWidget widget = findWidget(buddy);
-				if (null != widget) {
-					friendsWidgets.remove(widget);
-					widget.dispose(false);
-					canvas.layout(true);
-					Rectangle r = scrollable.getClientArea();
-					scrollable.setMinSize(canvas.computeSize(r.width, SWT.DEFAULT));
-					canvas.redraw();
-				}
-			}
-		});
-
-	}
-
-	public void clear() {
-		for (Iterator iterator = friendsWidgets.iterator(); iterator.hasNext();) {
-			FriendWidget widget = (FriendWidget) iterator.next();
-			widget.dispose(false);
-		}
-		friendsWidgets.clear();
-		Rectangle r = scrollable.getClientArea();
-		scrollable.setMinSize(canvas.computeSize(r.width, SWT.DEFAULT));
-	}
-
-	public FriendWidget findWidget(VuzeBuddy buddy) {
-		if (null != buddy) {
-			for (Iterator iterator = friendsWidgets.iterator(); iterator.hasNext();) {
-				FriendWidget widget = (FriendWidget) iterator.next();
-				if (null != widget.getBuddy()
-						&& widget.getBuddy().getLoginID().equals(buddy.getLoginID())) {
-					return widget;
-				}
-			}
-		}
-		return null;
-
-	}
-
-	public Control getControl() {
-		return content;
-	}
-
-	private class FriendWidget
-	{
-		private Composite parent;
-
-		private Canvas friendCanvas;
-
-		private VuzeBuddy buddy;
-
-		private Rectangle closeButtonBounds;
-
-		private Rectangle textAreaBounds;
-
-		private Color normalColor = null;
-
-		private Color borderColor = null;
-
-		private boolean isActive = false;
-
-		private boolean closeIsActive = false;
-
-		private int alpha = 255;
-
-		private Font boldFont = null;
-
-		private Font normalFont = null;
-
-		private FriendWidget(Composite parent, VuzeBuddy buddy) {
-			this.parent = parent;
-			this.buddy = buddy;
-
-			final ImageLoader imageLoader = ImageLoader.getInstance();
-			
-			closeButtonBounds = imageLoader.getImage("button_skin_close").getBounds();
-			imageLoader.releaseImage("button_skin_close");
-
-			//			activeColor = SWTSkinFactory.getInstance().getSkinProperties().getColor(
-			//					"color.row.selected");
-			normalColor = SWTSkinFactory.getInstance().getSkinProperties().getColor(
-					"color.table.bg");
-
-			borderColor = SWTSkinFactory.getInstance().getSkinProperties().getColor(
-					"color.widget.border");
-
-			friendCanvas = new Canvas(parent, SWT.DOUBLE_BUFFERED);
-			friendCanvas.setBackgroundMode(SWT.INHERIT_DEFAULT);
-
-			friendCanvas.addControlListener(new ControlAdapter() {
-				public void controlResized(ControlEvent e) {
-					Rectangle bounds = friendCanvas.getBounds();
-					closeButtonBounds.x = bounds.width - closeButtonBounds.width - 6;
-					closeButtonBounds.y = (bounds.height / 2)
-							- (closeButtonBounds.height / 2);
-					textAreaBounds = new Rectangle(6, 0, closeButtonBounds.x - 6,
-							bounds.height);
-				}
-			});
-
-			friendCanvas.addMouseTrackListener(new MouseTrackAdapter() {
-
-				public void mouseEnter(MouseEvent e) {
-					if (false == isEmailDisplayOnly()) {
-						isActive = true;
-						friendCanvas.redraw();
-					}
-				}
-
-				public void mouseExit(MouseEvent e) {
-					if (false == isEmailDisplayOnly()) {
-						isActive = false;
-						friendCanvas.redraw();
-					}
-				}
-
-				public void mouseHover(MouseEvent e) {
-					super.mouseHover(e);
-				}
-
-			});
-
-			friendCanvas.addMouseListener(new MouseAdapter() {
-
-				public void mouseUp(MouseEvent e) {
-					if (false == isEmailDisplayOnly()) {
-						if (true == closeButtonBounds.contains(e.x, e.y)) {
-							if (true == closeIsActive) {
-								//								removeFriend(FriendWidget.this.buddy);
-								getBuddiesViewer().removeFromShare(FriendWidget.this.buddy);
-							}
-						}
-					}
-				}
-
-			});
-			friendCanvas.addMouseMoveListener(new MouseMoveListener() {
-
-				public void mouseMove(MouseEvent e) {
-					if (false == isEmailDisplayOnly()) {
-						if (true == closeButtonBounds.contains(e.x, e.y)) {
-							if (false == closeIsActive) {
-								closeIsActive = true;
-								friendCanvas.redraw();
-							}
-						} else {
-							if (true == closeIsActive) {
-								closeIsActive = false;
-								friendCanvas.redraw();
-							}
-						}
-					}
-				}
-
-			});
-			friendCanvas.addPaintListener(new PaintListener() {
-
-				public void paintControl(PaintEvent e) {
-
-					if (null == boldFont) {
-						normalFont = e.gc.getFont();
-						FontData[] fData = e.gc.getFont().getFontData();
-						for (int i = 0; i < fData.length; i++) {
-							fData[i].setStyle(SWT.BOLD);
-						}
-						boldFont = new Font(e.display, fData);
-
-						friendCanvas.addDisposeListener(new DisposeListener() {
-
-							public void widgetDisposed(DisposeEvent e) {
-								if (null != boldFont && false == boldFont.isDisposed()) {
-									boldFont.dispose();
-								}
-							}
-						});
-					}
-
-					/*
-					 * Paints the background 
-					 */
-
-					Rectangle innerBounds = friendCanvas.getClientArea();
-
-					if (normalColor != null) {
-						e.gc.setBackground(normalColor);
-					}
-					e.gc.fillRectangle(innerBounds);
-
-					/*
-					 * Paints the border
-					 */
-					if (borderColor != null) {
-  					e.gc.setForeground(borderColor);
-  					e.gc.drawLine(0, innerBounds.height - 1, innerBounds.width,
-  							innerBounds.height - 1);
-					}
-
-					/*
-					 * Paint the text
-					 */
-//					if (textColor != null) {
-//						e.gc.setForeground(textColor);
-//					}
-					VuzeBuddy vbuddy = FriendWidget.this.buddy;
-
-					Rectangle displayNameBounds = new Rectangle(textAreaBounds.x,
-							textAreaBounds.y, textAreaBounds.width, textAreaBounds.height);
-
-					if (null != vbuddy.getDisplayName()
-							&& vbuddy.getDisplayName().length() > 0) {
-						e.gc.setFont(boldFont);
-
-						Point extent = e.gc.textExtent(vbuddy.getDisplayName() + " ");
-
-						displayNameBounds.width = extent.x;
-						GCStringPrinter.printString(e.gc, vbuddy.getDisplayName() + " ",
-								displayNameBounds, false, true, SWT.LEFT);
-
-						displayNameBounds.x = extent.x + 6;
-						displayNameBounds.width = textAreaBounds.width - extent.x;
-						e.gc.setFont(normalFont);
-
-						if (null != vbuddy.getLoginID() && vbuddy.getLoginID().length() > 0) {
-							GCStringPrinter.printString(e.gc,
-									"(" + vbuddy.getLoginID() + ")", displayNameBounds, false,
-									true, SWT.LEFT);
-						}
-					}
-
-					else {
-						if (null != vbuddy.getLoginID() && vbuddy.getLoginID().length() > 0) {
-							GCStringPrinter.printString(e.gc, vbuddy.getLoginID(),
-									displayNameBounds, false, true, SWT.LEFT);
-						}
-					}
-					/*
-					 * Paint the close button
-					 */
-					if (false == isEmailDisplayOnly()) {
-						String id = closeIsActive ? "button_skin_close-over"
-								: "button_skin_close";
-						Image img = imageLoader.getImage(id);
-						e.gc.drawImage(img, closeButtonBounds.x, closeButtonBounds.y);
-						imageLoader.releaseImage(id);
-					}
-				}
-			});
-		}
-
-		public VuzeBuddy getBuddy() {
-			return buddy;
-		}
-
-		public void setBuddy(VuzeBuddy buddy) {
-			this.buddy = buddy;
-		}
-
-		public void dispose(boolean animated) {
-			if (null != friendCanvas && false == friendCanvas.isDisposed()) {
-				if (true == animated) {
-					parent.getDisplay().asyncExec(new AERunnable() {
-
-						public void runSupport() {
-
-							/*
-							 * KN: TODO: disposal check is still not complete since it could still happen
-							 * between the .isDisposed() check and the .redraw() or .update() calls.
-							 */
-							while (alpha > 20 && false == friendCanvas.isDisposed()) {
-								alpha -= 40;
-								friendCanvas.redraw();
-								friendCanvas.update();
-
-								try {
-									Thread.sleep(50);
-								} catch (InterruptedException e) {
-									e.printStackTrace();
-								}
-							}
-
-							if (false == friendCanvas.isDisposed()) {
-								friendCanvas.dispose();
-								parent.layout(true);
-							}
-						}
-					});
-				} else {
-					if (false == friendCanvas.isDisposed()) {
-						friendCanvas.dispose();
-						parent.layout(true);
-					}
-				}
-
-			}
-		}
-
-		public Control getControl() {
-			return friendCanvas;
-		}
-	}
-
-	public boolean isEmailDisplayOnly() {
-		return isEmailDisplayOnly;
-	}
-
-	public void setEmailDisplayOnly(boolean isEmailDisplayOnly) {
-		this.isEmailDisplayOnly = isEmailDisplayOnly;
-	}
-
-	public BuddiesViewer getBuddiesViewer() {
-		return buddiesViewer;
-	}
-
-	public void setBuddiesViewer(BuddiesViewer buddiesViewer) {
-		this.buddiesViewer = buddiesViewer;
-	}
-
-	public int getContentCount() {
-		return friendsWidgets.size();
-	}
-
-	public List getFriends() {
-		List vuzeBuddies = new ArrayList();
-		for (Iterator iterator = friendsWidgets.iterator(); iterator.hasNext();) {
-			FriendWidget widget = (FriendWidget) iterator.next();
-			vuzeBuddies.add(widget.getBuddy());
-		}
-		return vuzeBuddies;
-	}
-
-	public Image getDefault_prompt_image() {
-		return default_prompt_image;
-	}
-
-	public void setDefault_prompt_image(Image default_prompt_image) {
-		this.default_prompt_image = default_prompt_image;
-	}
-
-	public String getDefault_prompt_text() {
-		return default_prompt_text;
-	}
-
-	public void setDefault_prompt_text(String default_prompt_text) {
-		this.default_prompt_text = default_prompt_text;
-	}
-}
diff --git a/com/aelitis/azureus/util/AzpdFileAccess.java b/com/aelitis/azureus/util/AzpdFileAccess.java
deleted file mode 100644
index 1459c5c..0000000
--- a/com/aelitis/azureus/util/AzpdFileAccess.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * Created on Feb 28, 2008
- * Created by Alan Snyder
- * Copyright (C) 2007 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package com.aelitis.azureus.util;
-
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.FileUtil;
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrentException;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Map;
-
-import com.aelitis.azureus.core.messenger.config.PlatformDCAdManager;
-
-public class AzpdFileAccess {
-
-	public static final String PARAM_EXPIRE_TIME = "az-expire-time";
-	public static final String PARAM_CREATE_TIME = "az-create-time";
-
-	public static final String PARAM_IS_OFFLINE = "is-off-line";
-
-	/**
-	 *
-	 * @param azpdFile -
-	 * @return - true if expired.
-	 */
-	public static synchronized boolean isAzpdFileExpired(File azpdFile){
-
-		try{
-			if (!azpdFile.exists()) {
-				return true;
-			}
-			
-			//turn this string into a Map.
-			Map params = readAzpdFileToMap(azpdFile);
-
-			String expireString = (String) params.get(PARAM_EXPIRE_TIME);
-
-			//any file without an "expire-time" entry in considered old, and needs to be refreshed.
-			if(expireString==null){
-				return true;
-			}
-
-			long expireTime = Long.parseLong(expireString);
-			long currTime = System.currentTimeMillis();
-
-			return ( currTime > expireTime );
-
-		}catch(IOException ioe){
-			//consider this file expired.
-			ioe.printStackTrace();
-			return true;
-		}catch(Exception e){
-			e.printStackTrace();
-			return true;
-		}
-	}
-
-	public static synchronized String readAzpdFile(File azpdFile)
-		throws IOException
-	{
-		String data = FileUtil.readFileAsString(azpdFile,10000000);
-		return data;
-	}
-
-	public static synchronized Map readAzpdFileToMap(File azpdFile)
-		throws IOException
-	{
-		String data = readAzpdFile(azpdFile);
-		return JSONUtils.decodeJSON(data);
-	}
-
-
-
-	public static synchronized void writeAzpdFile(File azpdFile, String data){
-		FileUtil.writeBytesAsFile(azpdFile.getAbsolutePath(),data.getBytes());
-	}
-
-    static final String EXT_AZUREUS_PLAYER_DATA = "azpd";
-    public static synchronized Map getPlayerDataMap(DownloadManager dm)
-    {
-        try
-        {
-            File azureusPlayDataFile = determineAzpdFileLocation(dm);
-
-			String data = AzpdFileAccess.readAzpdFile(azureusPlayDataFile);
-
-			return JSONUtils.decodeJSON(data);
-
-        }catch(TOTorrentException tte){
-            PlatformDCAdManager.debug("TOTorrent Error - getPlayerDataMap(): "+tte);
-            tte.printStackTrace();
-            return null;
-        }catch(Throwable t){
-
-            PlatformDCAdManager.debug("Error - getPlayerDataMap(): "+t);
-            t.printStackTrace();
-
-            return null;
-        }
-
-    }//getPlayerDataMap
-
-
-    /**
-     * Get the location of the azpd file.
-     * @param dm - DownloadManager
-     * @return - File -
-     * @throws TOTorrentException - t
-     */
-    public static File determineAzpdFileLocation(DownloadManager dm)
-        throws TOTorrentException
-    {
-    	try {
-        File azpdDir = getAzpdDir();
-
-        String fileNamePrefix = dm.getTorrent().getHashWrapper().toBase32String();
-        return new File( azpdDir ,fileNamePrefix+"."+EXT_AZUREUS_PLAYER_DATA );
-    	} catch (TOTorrentException te) {
-    		throw te;
-    	} catch (Exception e) {
-    		Debug.out("determineAzpdFileLocation: " + e.toString());
-    		return null;
-    	}
-    }
-
-    public static File getAzpdDir() {
-        File mediaDir = FileUtil.getUserFile("media");
-        if( !mediaDir.exists() ){
-            FileUtil.mkdirs(mediaDir);
-        }
-        File azpdDir = new File(mediaDir,"azpd");
-        if( !azpdDir.exists() ){
-            FileUtil.mkdirs(azpdDir);
-        }
-        return azpdDir;
-    }
-
-}
diff --git a/com/aelitis/azureus/util/ConstantsVuze.java b/com/aelitis/azureus/util/ConstantsVuze.java
index 4d028ff..36621ff 100644
--- a/com/aelitis/azureus/util/ConstantsVuze.java
+++ b/com/aelitis/azureus/util/ConstantsVuze.java
@@ -36,12 +36,6 @@ public class ConstantsVuze
 
 	public static final long DEFAULT_CONTENT_NETWORK_ID = ContentNetwork.CONTENT_NETWORK_VUZE;
 
-	/**
-	 * This verifier value is only used to validate that the page we're loading is
-	 * in-fact a page from Vuze; mainly required by the LightBoxBrowserWindow
-	 */
-	public static final String URL_PAGE_VERIFIER_VALUE = "vuzePage";
-
 	public static final boolean DIAG_TO_STDOUT = System.getProperty(
 			"DIAG_TO_STDOUT", "0").equals("1");
 
diff --git a/com/aelitis/azureus/util/DCAdManager.java b/com/aelitis/azureus/util/DCAdManager.java
deleted file mode 100644
index 65ac78e..0000000
--- a/com/aelitis/azureus/util/DCAdManager.java
+++ /dev/null
@@ -1,1072 +0,0 @@
-package com.aelitis.azureus.util;
-
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.download.EnhancedDownloadManager;
-import com.aelitis.azureus.core.download.DownloadManagerEnhancer;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.core.torrent.MetaDataUpdateListener;
-import com.aelitis.azureus.core.messenger.config.PlatformDCAdManager;
-
-import java.util.*;
-import java.io.File;
-import java.io.IOException;
-
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.download.ForceRecheckListener;
-import org.gudy.azureus2.core3.download.impl.DownloadManagerAdapter;
-import org.gudy.azureus2.core3.global.GlobalManager;
-import org.gudy.azureus2.core3.global.GlobalManagerAdapter;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.torrent.TOTorrentException;
-import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
-
-/**
- * Created on Feb 8, 2008
- * Created by Alan Snyder
- * Copyright (C) 2007 Aelitis, All Rights Reserved.
- * <p/>
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * <p/>
- * AELITIS, SAS au capital de 63.529,40 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-
-public class DCAdManager implements PlatformDCAdManager.GetAdvertDataReplyListener
-{
-	private static DCAdManager instance=null;
-
-	private static final long TIMEOUT_CHECKINGFORADS_MS = 1000L * 120; // 2 min
-
-	private final static long EXPIRE_ASX = 1000L * 60 * 10; // 10 min
-
-	private AzureusCore core;
-	private List adsDMList = new ArrayList();
-	private List adSupportedDMList = new ArrayList();
-
-	private Object lastVuzeId;
-
-	/**
-	 * A counter of the number of things happening that involve checking
-	 * for ads.
-	 */
-	private int checkingForAds = 0;
-
-	/**
-	 * The last time we increased checkingForAds.  Allows us to timeout
-	 * checkingForAds if something went awry.
-	 */
-	private long lastCheckingForAds = 0;
-
-	public static synchronized DCAdManager getInstance()
-	{
-		if(instance==null){
-			instance = new DCAdManager();
-		}
-		return instance;
-	}
-
-	private DCAdManager(){
-
-	}
-
-
-	public void initialize(final AzureusCore _core){
-		core = _core;
-
-		//start the impression tracker.
-		startAdTrackerListener();
-
-		GlobalManager gm = core.getGlobalManager();
-		gm.addListener(new GlobalManagerAdapter() {
-
-			/**
-			 * Delete and ASX, or azpd files when deleting the content.
-			 * @param dm -
-			 */
-			public void downloadManagerRemoved(DownloadManager dm) {
-				adsDMList.remove(dm);
-
-				//remove ASX file.
-				deleteAsxFile(dm);
-
-				//remove media/azpd  file.
-				deleteAzpdFile(dm);
-
-			}//downloadManagerRemoved
-
-			/**
-			 * Add information about the torrent.
-			 * @param dm -
-			 */
-			public void downloadManagerAdded(final DownloadManager dm) {
-
-				TOTorrent torrent = dm.getTorrent();
-
-				if (PlatformTorrentUtils.isContentAdEnabled(torrent)) {
-					//add location of ASX file.
-					dm.setData("ASX", determineASXFileLocation(dm));
-					//add location of azpd file.
-					try{
-						dm.setData("azpd", AzpdFileAccess.determineAzpdFileLocation(dm));
-					}catch(TOTorrentException tote){
-						debug("Failed to set azpd location",tote);
-					}
-				}
-
-				downloadManagerAddedHook(new DownloadManager[] {
-						dm
-				}, 0);
-			}//downloadManagerAdded
-
-		}, false); //addListener
-
-		//Get all the torrents on the system.
-		DownloadManager[] dms = (DownloadManager[]) gm.getDownloadManagers().toArray(
-				new DownloadManager[0]);
-		initDownloadManagerLists(dms);
-
-
-		//Add MetaData Update Listener.
-		PlatformTorrentUtils.addListener(new MetaDataUpdateListener() {
-			public void metaDataUpdated(TOTorrent torrent) {
-				GlobalManager gm = core.getGlobalManager();
-				DownloadManager dm = gm.getDownloadManager(torrent);
-				if (dm != null
-						&& PlatformTorrentUtils.isContentAdEnabled(dm.getTorrent())) {
-					downloadManagerAddedHook(new DownloadManager[] {
-							dm
-					}, 0);
-				}
-			}
-		});
-
-		//send the unsent impressions.
-		PlatformDCAdManager.loadUnsentImpressions();
-		PlatformDCAdManager.sendUnsentImpressions(5000);
-
-		//Wait a few minute then start a thead to check the azpd files that expired.
-		startAzpdFileCheckTimer(dms);
-	}//initialize
-
-
-	private void startAzpdFileCheckTimer(final DownloadManager[] dms)
-	{
-
-		final long INIT_WAIT_TIME = 1000 * 60 * 5; //wait 5 minutes between checks.
-
-		long startTime = System.currentTimeMillis() + INIT_WAIT_TIME;
-
-		SimpleTimer.addEvent("azpdFileExpireThreadStartTimer",
-				startTime,
-				new TimerEventPerformer(){
-
-			public void perform(TimerEvent event) {
-
-				startLazyAzpdFileCheckThread(dms);
-			}
-
-		} );
-	}
-
-
-	/**
-	 * @param dms - DownloadManager[]
-	 */
-	private void startLazyAzpdFileCheckThread(final DownloadManager[] dms){
-
-		final String THREAD_NAME = "azpdFileExpireThread";
-
-		AEThread2 thread = new AEThread2(THREAD_NAME,true){
-
-			public void run() {
-
-				if(dms==null){
-					debug(THREAD_NAME+": exit");
-					return;
-				}
-
-				if( dms.length==0){
-					debug(THREAD_NAME+": exit. Nothing to check.");
-					return;
-				}
-
-				debug(THREAD_NAME+": starting.");
-
-				int size = dms.length;
-				for(int i=0; i<size; i++){
-
-					DownloadManager dm = dms[i];
-
-					//is this AdEnabled Content?
-					if( isAdEnabledContent(dm) ){
-						File f;
-						try{
-							f = AzpdFileAccess.determineAzpdFileLocation(dm);
-						}catch(TOTorrentException tot){
-							debug(THREAD_NAME+": had "+tot.getMessage() );
-							f=null;
-						}
-						if(f==null)
-							continue;
-
-						//debug(THREAD_NAME+": checking "+f.getAbsolutePath());
-						if( AzpdFileAccess.isAzpdFileExpired(f) ){
-
-							debug(THREAD_NAME+": found expired azpd file "+f+". Will refresh. ");
-							//refresh this file.
-							downloadManagerAddedHook( new DownloadManager[] { dm }, 1000 );
-						}
-
-					}//if - isAdEnabledContent
-
-				}//for
-
-
-				debug(THREAD_NAME+": finished.");
-			}
-		};
-		
-		thread.setPriority(Thread.MIN_PRIORITY);
-		thread.start();
-	}
-
-	/**
-	 * Is this DownloadManager Ad Enabled?
-	 * @param dm -
-	 * @return -
-	 */
-	public static boolean isAdEnabledContent(DownloadManager dm){
-
-		TOTorrent torrent = dm.getTorrent();
-
-		return  (PlatformTorrentUtils.isContent(torrent, true)  &&
-				PlatformTorrentUtils.isContentAdEnabled(torrent) );
-	}
-
-
-	/**
-	 * Delete the ASX file. Tries transient data first, then looks up the likely directory.
-	 * @param dm - DownloadManager -
-	 */
-	private void deleteAsxFile(DownloadManager dm) {
-		File asxFile = (File) dm.getData("ASX");
-		if (asxFile != null) {
-			try {
-				asxFile.delete();
-			} catch (Exception e) {
-				debug("failed to delete file: "+asxFile.getAbsolutePath() );
-			}
-		}else{
-			try{
-				asxFile = determineASXFileLocation(dm);
-				if(asxFile!=null){
-					asxFile.delete();
-				}
-			}catch(Exception e){
-				debug("error while deleting asx file.",e);
-			}
-		}
-	}
-
-	/**
-	 * Delete the azpd file. tries the transisent data first, the looks up the
-	 * directory.
-	 * @param dm - DownloadManager - 
-	 */
-	private void deleteAzpdFile(DownloadManager dm) {
-		File azpdFile = (File) dm.getData("azpd");
-		if (azpdFile != null){
-			try {
-				azpdFile.delete();
-			} catch (Exception e){
-				debug("failed to delete azpd file: "+azpdFile.getAbsolutePath() );
-			}
-		}else{
-			try{
-				//the data was not persistent look in the expected directory.
-				azpdFile = AzpdFileAccess.determineAzpdFileLocation(dm);
-				if(azpdFile != null){
-					azpdFile.delete();
-				}
-			}catch(Exception e){
-				debug("error while deleting azpd file.",e);
-			}
-		}
-	}
-
-	private void startAdTrackerListener() {
-		ExternalStimulusHandler.addListener(new ExternalStimulusListener() {
-			public boolean receive(String name, Map values) {
-				if (values == null) {
-					return false;
-				}
-
-				if (name.equals("adtracker")) {
-					processImpression(values);
-					return true;
-				}
-
-				return false;
-			}
-
-
-			/**
-			 * @param name -
-			 * @param values -
-			 * @return  -
-			 */
-			public int query(String name, Map values) {
-				return Integer.MIN_VALUE;
-			}
-		});
-	}
-
-
-	/**
-	 * Is callback from player.
-	 * @param values - parameters from the AdTracking URL.
-	 */
-	protected void processImpression(Map values) {
-
-		try {
-			String contentHash = (String) values.get("contentHash");
-			if (contentHash == null) {
-				debug("No Content Hash on processImpression!");
-				return;
-			}
-
-			String impressionID = (String) values.get("impressionTracker");
-			if( impressionID==null ){
-				debug("No impressionTracker");
-				return;
-			}
-
-			String thirdPartyImpressionUrl = (String) values.get("thirdPartyImp");
-			if( thirdPartyImpressionUrl == null ) {
-				thirdPartyImpressionUrl = "";
-			}
-			
-			//The vuzeId is used to keep impressions unique.
-			String vuzeId = (String) values.get("vuzeId");
-			if( vuzeId==null ){
-				debug(" No vuzeId ");
-				return;
-			}
-
-			//don't count this impression if it is the same as the last one.
-			if(  vuzeId.equals(lastVuzeId) ){
-				return;
-			}
-			lastVuzeId = vuzeId;
-
-			String adHash = (String) values.get("srcURL");
-			if (adHash == null) {
-				debug("No srcURL");
-				return;
-			}
-
-			//Note this use to be called hash.
-			String torrentHash = (String) values.get("torrentHash");
-			if (torrentHash == null){
-				debug("No torrentHash");
-				return;
-			}
-
-			DownloadManager dmContent = null;
-			if (torrentHash != null) {
-				dmContent = core.getGlobalManager().getDownloadManager(
-						new HashWrapper(Base32.decode(torrentHash)));
-			}
-
-			if (dmContent == null) {
-				dmContent = core.getGlobalManager().getDownloadManager(
-						new HashWrapper(Base32.decode(contentHash)));
-			}
-			if (dmContent != null) {
-				debug("clear last asx for "
-						+ dmContent.getTorrent().getHashWrapper().toBase32String());
-				dmContent.setData("LastASX", null);
-			}
-
-			debug("imp " + impressionID + " commencing on "
-					+ contentHash + "/" + torrentHash);
-
-			DownloadManager dm = core.getGlobalManager().getDownloadManager(
-					new HashWrapper(Base32.decode(adHash)));
-			if (dm == null) {
-				debug("DM for Ad not found");
-			}
-
-			PlatformDCAdManager.saveImpression(impressionID,   // impressionID == doubleclick impression url
-					SystemTime.getCurrentTime(), contentHash, torrentHash, adHash, thirdPartyImpressionUrl,
-					5000);
-
-		} catch (Exception e) {
-			Debug.out(e);
-		}
-	}//processImpression
-
-
-	/**
-	 * Hook into a list of download managers, making sure they have an ad if
-	 * they need one.
-	 * 
-	 * @param dms -
-	 */
-	private void downloadManagerAddedHook(final DownloadManager[] dms,
-			final int delay) {
-		AEThread2 thread = new AEThread2("downloadManagerAddedHook", true) {
-			public void run() {
-				debug("enter - downloadManagerAddedHook");
-
-				try {
-					// Since there is a chance that we will find something ad-supported,
-					// mark this as checking for ads, so EMP doesn't hastily go off
-					// and play the content
-					increaseCheckingForAds();
-
-					List adSupportedContentList = initDownloadManagerLists(dms);
-
-					if (adSupportedContentList.size() == 0) {
-						debug("none of the " + dms.length
-								+ " new torrent(s) are ad enabled.  SKIPPING getAdvert");
-						//determine the reason torrents are not ad -enabled.
-						determineReasonAdNotEnabled(dms);
-						return;
-					} else {
-						//Add GetAdvert here.
-						callGetAdvert(adSupportedContentList, delay);
-					}
-
-				} finally {
-					decreaseCheckingForAds();
-				}
-
-				debug("exit - downloadManagerAddedHook");
-			}
-
-		};
-		thread.run();
-	}//downloadManagerAddedHook
-
-	private void callGetAdvert(List adSupportedContentList, int delay) {
-		try {
-			increaseCheckingForAds();
-			debug("sending ad request for " + adSupportedContentList.size()
-					+ " pieces of content.  We already have " + adsDMList.size() + " ads");
-			DownloadManager[] dmAdable = (DownloadManager[]) adSupportedContentList.toArray(new DownloadManager[0]);
-
-			//Get the advertisment.
-			for (int i = 0; i < dmAdable.length; i++) {
-				DownloadManager dm = dmAdable[i];
-
-				// each reply from getAdvert will in turn decreaseCheckingForAds()
-				increaseCheckingForAds();
-				PlatformDCAdManager.getAdvert(dm, delay, this);
-			}
-
-		} catch (Exception e) {
-			Debug.out(e);
-		} finally {
-			decreaseCheckingForAds();
-		}
-	}
-
-	/**
-	 * This is called when a GetAdvert message is sent to the platform
-	 */
-	// @see com.aelitis.azureus.core.messenger.config.PlatformDCAdManager.GetAdvertDataReplyListener#messageSent()
-	public void messageSent() {
-		//nothing needed here.
-	}
-
-	// @see com.aelitis.azureus.core.messenger.config.PlatformDCAdManager.GetAdvertDataReplyListener#adsReceived(java.util.List, java.util.Map)
-	public void adsReceived(List torrents, Map webParams) {
-		try {
-			debug("enter - adsReceived has #" + torrents.size() + " torrents");
-			for (Iterator iter = torrents.iterator(); iter.hasNext();) {
-				TOTorrent torrent = (TOTorrent) iter.next();
-				try {
-					debug("Ad: " + new String(torrent.getName()));
-
-					TorrentUtils.setFlag(torrent,
-							TorrentUtils.TORRENT_FLAG_LOW_NOISE, true);
-
-					//Add the adId if it is not here.
-					String adId = PlatformTorrentUtils.getAdId(torrent);
-					if( adId==null ){
-						PlatformTorrentUtils.setAdId(torrent,"1");
-					}
-
-					File tempFile = File.createTempFile("AZ_", ".torrent");
-
-					debug("  Writing to " + tempFile);
-					torrent.serialiseToBEncodedFile(tempFile);
-
-					String sDefDir = null;
-					try {
-						sDefDir = COConfigurationManager.getDirectoryParameter("Default save path");
-					} catch (IOException e) {
-					}
-
-					if (sDefDir == null) {
-						sDefDir = tempFile.getParent();
-					}
-
-					DownloadManager adDM = core.getGlobalManager().addDownloadManager(
-							tempFile.getAbsolutePath(), sDefDir);
-
-					if (adDM != null) {
-						if (adDM.getAssumedComplete()) {
-							adsDMList.add(adDM);
-							adDM.setForceStart(false);
-						} else {
-							adDM.setForceStart(true);
-							debug("Force Start " + adDM);
-							adDM.addListener(new DownloadManagerAdapter() {
-								public void downloadComplete(DownloadManager manager) {
-									if (!adsDMList.contains(manager)) {
-										adsDMList.add(manager);
-									}
-									manager.setForceStart(false);
-									manager.removeListener(this);
-								}
-							});
-						}
-						// TODO: Add Expiry date
-						debug("  ADDED ad " + adDM.getDisplayName());
-					}
-					tempFile.deleteOnExit();
-				} catch (Exception e) {
-					Debug.out(e);
-				}
-			}
-		} finally {
-			decreaseCheckingForAds();
-		}
-
-		debug("exit - adsReceived");
-	}
-
-	/**
-	 * This is called after an Advert request from the platform fails to produce
-	 * valid results
-	 */
-	// @see com.aelitis.azureus.core.messenger.config.PlatformDCAdManager.GetAdvertDataReplyListener#replyReceived(java.lang.String, java.util.Map)
-	public void replyReceived(String replyType, Map mapHashes) {
-		decreaseCheckingForAds();
-		debug("bad reply. " + mapHashes.get("text"));
-	}
-
-
-	/**
-	 * debugNotAdEnabledReason - which reason is a torrent not ad-enabled.
-	 * @param dms - DownloadManager[]
-	 */
-	private void determineReasonAdNotEnabled(final DownloadManager[] dms) {
-		for (int i = 0; i < dms.length; i++) {
-			final DownloadManager dm = dms[i];
-			TOTorrent torrent = dm.getTorrent();
-			StringBuffer sb = new StringBuffer();
-			sb.append( new String(torrent.getName()) ).append(" reasons: ");
-			if( PlatformTorrentUtils.isContent(torrent, true) ){ sb.append( "A-isContent , " ); }
-			if( PlatformTorrentUtils.getContentHash(torrent) != null ){ sb.append( "B-getConentHash , " ); }
-			if( PlatformTorrentUtils.isContentAdEnabled(torrent)){ sb.append( "C-isContentAdEnabled" ); }
-			debug( sb.toString() );
-		}//for
-	}//determineReasonAdNotEnabled
-
-	/**
-	 * Determine the location of the ASX file. Should be in the same directory as content if possible.
-	 * @param dm - download manager.
-	 * @return - File with name of file.
-	 */
-	private File determineASXFileLocation(DownloadManager dm) {
-		debug("determineASXFileLocation");
-		EnhancedDownloadManager edm = DownloadManagerEnhancer.getSingleton().getEnhancedDownload(
-				dm);
-		File file;
-		if (edm != null) {
-			file = edm.getPrimaryFile().getFile(true);
-		} else {
-			file = new File(dm.getDownloadState().getPrimaryFile());
-		}
-		return new File(file.getAbsolutePath() + ".asx");
-	}
-
-	/**
-	 * For the content associated with the DownloadManager read the PlayerDataMap file from
-	 * the "media/azpd" directory, find the URLs for the ad and content. Then return that
-	 * ASX file as a String.
-	 *
-	 * @param dmContent - DownloadManager for the content.
-	 * @return String - completed playlist.
-	 */
-	public String replaceASXParams(final DownloadManager dmContent)
-	{
-
-		debug("replaceASXParams");
-		//Look for the PlayerDataMap file.
-		Map playerDataMap = AzpdFileAccess.getPlayerDataMap(dmContent);
-		String origPlaylist = (String) playerDataMap.get("playlist");
-
-		if( origPlaylist==null ){
-			debug("The data map is missing 'playlist' key. - playerDataMap="+playerDataMap);
-
-			throw new IllegalStateException("The data map is missing 'playlist' key: "+playerDataMap);
-		}
-
-
-		//Replace the following params in the original playlist
-		StringBuffer repBuffer = new StringBuffer(origPlaylist);
-
-
-		String contentPath = PlayUtils.getContentUrl(dmContent);
-
-		debug("  contentPath: "+contentPath);
-		replace(repBuffer,"<##-CONTENT-PATH-##>",contentPath);
-
-
-		boolean isNullAd = determinIfNullAd(dmContent);
-		if( !isNullAd ){
-			//Find location of the ad(s).
-			try {
-  			List<File> ads = getAdMediaFromContentDownloadManager(dmContent);
-  			if (ads.size() > 0) {
-  				File adFile = ads.get(0);
-    			debug("  adPath: "+adFile.getAbsolutePath());
-    			replace(repBuffer,"<##-AD-PATH-##>",adFile.getAbsolutePath());
-    			
-    			for (int i = 0; i < ads.size(); i++) {
-						adFile = ads.get(i);
-						if (adFile != null) {
-							replace(repBuffer, "<##-AD-PATH-" + i + "-##>",
-									adFile.getAbsolutePath());
-						}
-					}
-  			}
-			} catch (Exception e) {
-				debug("reokacASXParams: " + e.toString());
-	  			replace(repBuffer,"<##-AD-PATH-##>","http://www.vuze.com/img43/asx_noad.gif");
-			}
-
-			String newRepBuffer = repBuffer.toString().replaceAll(
-					"<##-AD-PATH-[0-9]+-##>", "http://www.vuze.com/img43/asx_noad.gif");
-			repBuffer.delete(0, repBuffer.length());
-			repBuffer.append(newRepBuffer);
-		}
-
-		//pass the params to the player via the download manager.
-		addParmasToDownloadManager(dmContent,playerDataMap);
-
-		return repBuffer.toString();
-	}//replaceASXParams
-
-	/**
-	 * If the map returned from the server has a lenght of zero, this assume this is
-	 * a NullAd type. This means that the playlist should not have a AD-PATH in it.
-	 * @param contentDM - DownloadManager has Map returned from web-server.
-	 * @return  -  boolean - true if null ad, false otherwise.
-	 */
-	private boolean determinIfNullAd(DownloadManager contentDM){
-
-		Map map = AzpdFileAccess.getPlayerDataMap(contentDM);
-		List adHashList = (List) map.get("ad_hash");
-
-		if(adHashList==null){
-			return true;
-		}
-
-		//is a null ad it size is zero, otherwise not a null ad.
-		return (adHashList.size() <= 0);
-	}//determineIfNullAd
-
-
-	/**
-	 * The azdp data is passed to the embedded player via the DownloadManager
-	 * @param dmContent - download manager.
-	 * @param playerData - Map with player data.
-	 */
-	public static void addParmasToDownloadManager(DownloadManager dmContent, Map playerData){
-
-		//String add a time-stamp to the map which can be used to expire it.
-		String createTime = ""+System.currentTimeMillis();
-		playerData.put("create-time",createTime);
-
-		//The key must be in synch with the embedded player.
-		dmContent.setData("web-ad-params",playerData);
-
-	}//addParamsToDownloadManager
-
-	/**
-	 * a) Read the file in media/azpd
-	 * (b) determine the location of the advert.
-	 * (c) write it to the location specified.
-	 * @param asxFileLocation - Location of ASX file to build.
-	 * @param dmContent - DownloadManager
-	 */
-	public void writeASXFile(final File asxFileLocation,
-			final DownloadManager dmContent)
-	{
-		String finishedASX = replaceASXParams(dmContent);
-		FileUtil.writeBytesAsFile(asxFileLocation.getAbsolutePath(), finishedASX.getBytes() );
-	}
-
-	private static void replace(StringBuffer sb, String param, String value){
-		replace(sb,param,value,0);
-	}//replace
-
-
-
-	private static void replace(StringBuffer sb, String param, String value, int startIndex){
-
-		int s = sb.indexOf(param,startIndex);
-		if (s >= 0) {
-			sb.replace(s, s+param.length(), value );
-		}
-
-	}//replace
-
-	private List<File> getAdMediaFromContentDownloadManager(DownloadManager contentDM){
-
-		debug("getAdMediaFromContentDownloadManager");
-
-		GlobalManager gm = contentDM.getGlobalManager();
-		Map map = AzpdFileAccess.getPlayerDataMap(contentDM);
-		List adHashList = (List) map.get("ad_hash");
-
-		List<File> ads = new ArrayList<File>();
-		
-		for (Iterator iter = adHashList.iterator(); iter.hasNext();) {
-			String adHash = (String) iter.next();
-			if (adHash == null || adHash.equals("")) {
-				continue;
-			}
-
-			HashWrapper adHashWrapper = new HashWrapper(Base32.decode(adHash));
-			DownloadManager dmAd = gm.getDownloadManager(adHashWrapper);
-
-			File adFile;
-			if (dmAd != null) {
-				adFile = dmAd.getDiskManagerFileInfo()[0].getFile(true);
-				ads.add(adFile);
-			}
-		}
-
-		return ads;
-	}
-
-	/**
-	 * Temporary function so that EMP <= 2.0.4 can work
-	 * 
-	 * @param dm -
-	 * @param url -
-	 * @param createdListener -
-	 *
-	 * @since 3.0.4.3
-	 */
-	public void createASX(DownloadManager dm, String url,
-			ASXCreatedListener createdListener) {
-		createASX(dm, createdListener);
-	}
-
-	public void createASX(final DownloadManager dm,
-			final ASXCreatedListener asxCreatedListener) {
-		if (dm == null) {
-			debug("createASX - null dm");
-			return;
-		}
-		String name = dm.getDisplayName();
-
-		debug("enter - createASX");
-		try {
-			TOTorrent torrent = dm.getTorrent();
-			if (torrent == null || !PlatformTorrentUtils.isContent(torrent, true)) {
-				debug("createASX - " + name + " not our content");
-				return;
-			}
-
-			File asxFile;
-
-			//Check the age of the current ASX file.
-			Object lastASXObject = dm.getData("LastASX");
-			if (lastASXObject instanceof Long) {
-				long lastASX = ((Long) lastASXObject).longValue();
-				if (SystemTime.getCurrentTime() - lastASX < EXPIRE_ASX) {
-					asxFile = determineASXFileLocation(dm);
-					if (asxFile.isFile()) {
-						debug("playing " + name
-								+ " using existing asx: " + asxFile + "; expires in "
-								+ (EXPIRE_ASX - (SystemTime.getCurrentTime() - lastASX)));
-						if (asxCreatedListener != null) {
-							asxCreatedListener.asxCreated(asxFile);
-						}
-						return;
-					}
-				}
-			}
-
-			//Read the media/azpd/player data file - create an ASX file.
-			File newASXFile = determineASXFileLocation(dm);
-			writeASXFile(newASXFile,dm);
-
-			asxFile = determineASXFileLocation(dm);
-			if (asxFile.isFile()) {
-				debug("playing " + name + " using existing asx: " + asxFile);
-				if (asxCreatedListener != null) {
-					asxCreatedListener.asxCreated(asxFile);
-				}
-				return;
-			}
-
-			debug("getting asx for " + name);
-
-		} catch (Exception e) {
-			if (asxCreatedListener != null) {
-				asxCreatedListener.asxFailed();
-			}
-			debug("createASX exception for " + name, e);
-		}
-		debug("exit - createASX");
-	}//createASX
-
-
-	public interface ASXCreatedListener
-	{
-		public void asxCreated(File asxFile);
-
-		public void asxFailed();
-	}
-
-
-	/**
-	 * @param nowPlaying -
-	 * @return true if it is an ad
-	 * @since 3.0.2.3
-	 */
-	public boolean isAd(String nowPlaying) {
-		if (nowPlaying == null) {
-			return false;
-		}
-		File file = new File(nowPlaying);
-		DownloadManager[] ads = getAds(true);
-		for (int i = 0; i < ads.length; i++) {
-			DownloadManager downloadManager = ads[i];
-			DiskManagerFileInfo[] fileInfos = downloadManager.getDiskManagerFileInfo();
-			for (int j = 0; j < fileInfos.length; j++) {
-				DiskManagerFileInfo fileinfo = fileInfos[j];
-				File adFile = fileinfo.getFile(true);
-				if (adFile.equals(file)) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	public DownloadManager[] getAds(boolean bIncludeIncomplete) {
-
-
-		if (bIncludeIncomplete) {
-			debug("There are "+adsDMList.size()+" ads. including incomplete.");
-			return (DownloadManager[]) adsDMList.toArray(new DownloadManager[0]);
-		}
-
-		ArrayList ads = new ArrayList(adsDMList);
-		for (Iterator iter = ads.iterator(); iter.hasNext();) {
-			DownloadManager dm = (DownloadManager) iter.next();
-			if (!dm.getAssumedComplete()) {
-				iter.remove();
-			}
-		}
-
-		debug("There are " + ads.size() + " ads ");
-		return (DownloadManager[]) ads.toArray(new DownloadManager[0]);
-	}//getAds
-
-
-	/**
-	 * Maintain list of ad downloads, and ad-supported downloads, and make
-	 * they are in a good state
-	 *
-	 * @param dms - DownloadManager[]
-	 * @return - List
-	 */
-	List initDownloadManagerLists(DownloadManager[] dms) {
-
-		List adSupportedContentList = new ArrayList();
-
-		if (dms == null) {
-			return adSupportedContentList;
-		}
-
-		// build adSupportedContentList of ad supported content
-		for (int i = 0; i < dms.length; i++) {
-			final DownloadManager dm = dms[i];
-
-			TOTorrent torrent = dm.getTorrent();
-			if (torrent == null) {
-				return adSupportedContentList;
-			}
-
-			//If this torrent is an ad do this block.
-			if (PlatformTorrentUtils.getAdId(torrent) != null) {
-				// one of us!
-
-				try {
-					debug("found ad " + dm + ": " + PlatformTorrentUtils.getAdId(torrent)
-							+ ": " + dm.getTorrent().getHashWrapper().toBase32String());
-				} catch (TOTorrentException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-				if (!adsDMList.contains(dm)) {
-					adsDMList.add(dm);
-				}
-			}
-
-			//If the torrent is content that contains an ad, do this block.
-			// Notes:
-			//   PlatformTorrentUtils.isContent calls PlatformTorrentUtils.getContentHash
-			//   No need to check if content against tracker list.. if someone
-			// wants to fake ad-enabled support, no need to stop them
-			if (PlatformTorrentUtils.isContent(torrent, false)
-					&& PlatformTorrentUtils.isContentAdEnabled(torrent)) {
-				adSupportedContentList.add(dm);
-
-				if (!adSupportedDMList.contains(dm)) {
-
-					adSupportedDMList.add(dm);
-					if (!dm.getAssumedComplete()) {
-						dm.addListener(new DownloadManagerAdapter() {
-
-							/**
-							 * download complete
-							 * @param manager -
-							 */
-							public void downloadComplete(DownloadManager manager) {
-								// good chance we still have internet here, so get/cache
-								// the asx
-								debug("calling createASX from ...Hook, in torrent has AD block content="
-										+ dm.getDisplayName());
-
-								createASX(dm, null);
-
-							}//downloadComplete
-						});
-					}
-				}
-			}
-
-		}//for
-
-		if ( adsDMList.size() > 0 ){
-			
-			new AEThread2( "DCAdManager:adchecker", true )
-			{
-				public void
-				run()
-				{
-					for (int i=0;i<adsDMList.size();i++){
-						
-						DownloadManager dm = (DownloadManager)adsDMList.get(i);
-				
-						// Make sure it's started
-						// Note: We also used to check dm.filesExist(true)
-						//       but that's too time consuming at startup..
-						if (dm.getAssumedComplete()) { // && dm.filesExist(true)) {
-							dm.setForceStart(false);
-						} else {
-							if (dm.getState() == DownloadManager.STATE_ERROR) {
-								dm.forceRecheck(new ForceRecheckListener() {
-									public void forceRecheckComplete(DownloadManager dm) {
-										dm.setForceStart(true);
-									}
-								});
-							} else {
-								dm.setForceStart(true);
-							}
-							dm.addListener(new DownloadManagerAdapter() {
-								public void downloadComplete(DownloadManager manager) {
-									if (!adsDMList.contains(manager)) {
-										adsDMList.add(manager);
-									}
-									manager.setForceStart(false);
-									manager.removeListener(this);
-								}
-							});
-						}
-					}
-				}
-			}.start();
-		}
-		
-		return adSupportedContentList;
-	}//initDownloadManagerList
-
-
-	/**
-	 * Call when you want to refresh via getAdvert call (non-immediate)
-	 * @param dm - DownloadManager
-	 */
-	public void refreshAd(DownloadManager dm){
-		refreshAd(dm, false);
-	}
-
-	/**
-	 * Call when you want to refresh via getAdvert call.
-	 * @param dm - DownloadManager
-	 */
-	public void refreshAd(DownloadManager dm, boolean immediate){
-
-		downloadManagerAddedHook(new DownloadManager[] {
-			dm
-		}, immediate ? 0 : 1000);
-
-	}//refreshAd
-
-
-	private void increaseCheckingForAds() {
-		synchronized (this) {
-			checkingForAds++;
-			lastCheckingForAds = SystemTime.getCurrentTime();
-		}
-	}
-
-	private void decreaseCheckingForAds() {
-		synchronized (this) {
-			if (checkingForAds > 0) {
-				checkingForAds--;
-			}
-		}
-	}
-
-	public boolean isCheckingForNewAds() {
-		synchronized (this) {
-			if (SystemTime.getCurrentTime() - lastCheckingForAds > TIMEOUT_CHECKINGFORADS_MS) {
-				checkingForAds = 0;
-			}
-			return checkingForAds > 0;
-		}
-	}
-
-	private static void debug(String msg){
-		PlatformDCAdManager.debug("DCAdManager: "+msg);
-	}
-
-	private static void debug(String msg, Throwable t){
-		PlatformDCAdManager.debug("DCAdManager: "+msg,t);
-	}
-}//class
diff --git a/com/aelitis/azureus/util/DataSourceUtils.java b/com/aelitis/azureus/util/DataSourceUtils.java
index 0bfe69a..d9a7c92 100644
--- a/com/aelitis/azureus/util/DataSourceUtils.java
+++ b/com/aelitis/azureus/util/DataSourceUtils.java
@@ -26,10 +26,11 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.HashWrapper;
 
 import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.buddy.VuzeShareable;
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
+import com.aelitis.azureus.core.content.RelatedContent;
+import com.aelitis.azureus.core.devices.DeviceOfflineDownload;
 import com.aelitis.azureus.core.devices.TranscodeFile;
 import com.aelitis.azureus.core.devices.TranscodeJob;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
@@ -72,8 +73,6 @@ public class DataSourceUtils
 				return gm.getDownloadManager((TOTorrent) ds);
 			} else if (ds instanceof ISelectedContent) {
 				return getDM(((ISelectedContent)ds).getDownloadManager()); 
-			} else if (ds instanceof VuzeShareable) {
-				return getDM(((VuzeShareable)ds).getDownloadManager()); 
 			} else 	if (ds instanceof TranscodeJob) {
 				TranscodeJob tj = (TranscodeJob) ds;
 				try {
@@ -98,6 +97,8 @@ public class DataSourceUtils
 					}
 				} catch (DownloadException e) {
 				}
+			} else if (ds instanceof DeviceOfflineDownload ) {
+				return( PluginCoreUtils.unwrap(((DeviceOfflineDownload)ds).getDownload()));
 			}
 
 		} catch (Exception e) {
@@ -164,7 +165,12 @@ public class DataSourceUtils
 			}
 		}
 		
-		
+		if (ds instanceof DeviceOfflineDownload ){
+			Torrent torrent = ((DeviceOfflineDownload) ds).getDownload().getTorrent();
+			if (torrent != null) {
+				return PluginCoreUtils.unwrap(torrent);
+			}
+		}
 
 		if (ds instanceof ISelectedContent) {
 			return ((ISelectedContent)ds).getTorrent();
@@ -183,10 +189,6 @@ public class DataSourceUtils
 			}
 		}
 
-		if ( ds instanceof VuzeShareable ){
-			return getTorrent(((VuzeShareable)ds).getDownloadManager());
-		}
-		
 		return null;
 	}
 
@@ -214,13 +216,13 @@ public class DataSourceUtils
 				return ((DownloadManager) ds).getTorrent().getHashWrapper().toBase32String();
 			} else if (ds instanceof TOTorrent) {
 				return ((TOTorrent) ds).getHashWrapper().toBase32String();
+			} else if (ds instanceof DeviceOfflineDownload) {
+				return( getHash(PluginCoreUtils.unwrap(((DeviceOfflineDownload)ds).getDownload())));
 			} else if (ds instanceof VuzeActivitiesEntry) {
 				VuzeActivitiesEntry entry = (VuzeActivitiesEntry) ds;
 				return entry.getAssetHash();
 			} else if (ds instanceof ISelectedContent) {
 				return ((ISelectedContent)ds).getHash();
-			} else if (ds instanceof VuzeShareable) {
-				return ((VuzeShareable)ds).getHash();
 			} else if (ds instanceof String) {
 				return (String) ds;
 			}
@@ -237,13 +239,13 @@ public class DataSourceUtils
 				id = PlatformTorrentUtils.getContentNetworkID(((DownloadManager) ds).getTorrent());
 			} else if (ds instanceof TOTorrent) {
 				id = PlatformTorrentUtils.getContentNetworkID((TOTorrent) ds);
+			} else if (ds instanceof DeviceOfflineDownload) {
+				return( getContentNetwork(PluginCoreUtils.unwrap(((DeviceOfflineDownload)ds).getDownload())));
 			} else if (ds instanceof VuzeActivitiesEntry) {
 				VuzeActivitiesEntry entry = (VuzeActivitiesEntry) ds;
 				return entry.getContentNetwork();
 			} else if (ds instanceof ISelectedContent) {
 				return getContentNetwork(((ISelectedContent)ds).getDownloadManager());
-			} else if (ds instanceof VuzeShareable ) {
-				return getContentNetwork(((VuzeShareable)ds).getDownloadManager());
 			} else if ((ds instanceof String) && ((String)ds).length() == 32) {
 				// assume 32 byte string is a hash and that it belongs to the def. network
 				id = ConstantsVuze.getDefaultContentNetwork().getID();
@@ -273,6 +275,8 @@ public class DataSourceUtils
 					}
 				} catch (Throwable e) {
 				}
+			} else if (ds instanceof RelatedContent) {
+				id = ((RelatedContent)ds).getContentNetwork();
 			} else {
 				Debug.out("Tux: UH OH NO CN for " + ds + "\n" + Debug.getCompressedStackTrace());
 			}
@@ -293,9 +297,6 @@ public class DataSourceUtils
 		if (ds instanceof ISelectedContent) {
 			return ((ISelectedContent)ds).getDownloadInfo();
 		}
-		if (ds instanceof VuzeShareable ) {
-			return ((VuzeShareable)ds).getDownloadInfo();
-		}
 		return null;
 	}
 
diff --git a/com/aelitis/azureus/util/DownloadUtils.java b/com/aelitis/azureus/util/DownloadUtils.java
index 26b9d18..a6ca2a2 100644
--- a/com/aelitis/azureus/util/DownloadUtils.java
+++ b/com/aelitis/azureus/util/DownloadUtils.java
@@ -97,6 +97,13 @@ DownloadUtils
 		download.setAttribute( ta_tracker_extensions, value );
 	}
 	
+	public static synchronized String
+	getTrackerExtensions(
+		Download	download )
+	{
+		return( download.getAttribute( ta_tracker_extensions ));
+	}
+	
 	public static synchronized void
 	removeTrackerExtension(
 		Download	download,
diff --git a/com/aelitis/azureus/util/FAQTopics.java b/com/aelitis/azureus/util/FAQTopics.java
deleted file mode 100644
index aa17ce5..0000000
--- a/com/aelitis/azureus/util/FAQTopics.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.aelitis.azureus.util;
-
-public interface FAQTopics
-{
-
-	public static final String FAQ_TOPIC_WHAT_ARE_FRIENDS = "190";
-
-	public static final String FAQ_TOPIC_WHAT_IS_SECURE_SHARING = "191";
-}
diff --git a/com/aelitis/azureus/util/ILoginInfoListener.java b/com/aelitis/azureus/util/ILoginInfoListener.java
deleted file mode 100644
index e572daa..0000000
--- a/com/aelitis/azureus/util/ILoginInfoListener.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * 
- */
-package com.aelitis.azureus.util;
-
-import com.aelitis.azureus.util.LoginInfoManager.LoginInfo;
-
-public interface ILoginInfoListener
-{
-	public void loginUpdate(LoginInfo info, boolean isNewLoginID);
-	
-	public void avatarURLUpdated(String newAvatarURL);
-}
\ No newline at end of file
diff --git a/com/aelitis/azureus/util/InitialisationFunctions.java b/com/aelitis/azureus/util/InitialisationFunctions.java
index cb98039..a45fc11 100644
--- a/com/aelitis/azureus/util/InitialisationFunctions.java
+++ b/com/aelitis/azureus/util/InitialisationFunctions.java
@@ -62,7 +62,7 @@ public class InitialisationFunctions
 		
 		DownloadManagerEnhancer dme = DownloadManagerEnhancer.initialise(core);
 
-		registerTrackerURLExtensions();
+		hookDownloadAddition();
 
 		AzureusPlatformContentDirectory.register();
 
@@ -160,7 +160,7 @@ public class InitialisationFunctions
 	}
 
 	protected static void 
-	registerTrackerURLExtensions() 
+	hookDownloadAddition() 
 	{
 		PluginInterface pi = PluginInitializer.getDefaultInterface();
 
@@ -175,6 +175,17 @@ public class InitialisationFunctions
 				initialised(
 					Download 	download )
 				{
+						// unfortunately the has-been-opened state is updated by azureus when a user opens content
+						// but is also preserved across torrent export/import (e.g. when downloaded via magnet
+						// URL. So reset it here if it is found to be set
+					
+					org.gudy.azureus2.core3.download.DownloadManager dm = PluginCoreUtils.unwrap( download );
+					
+					if ( PlatformTorrentUtils.getHasBeenOpened( dm )){
+						
+						PlatformTorrentUtils.setHasBeenOpened( dm, false );
+					}
+					
 					register( download );
 				}
 			});
diff --git a/com/aelitis/azureus/util/JSFunctionParametersParser.java b/com/aelitis/azureus/util/JSFunctionParametersParser.java
deleted file mode 100644
index 800632b..0000000
--- a/com/aelitis/azureus/util/JSFunctionParametersParser.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.aelitis.azureus.util;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class JSFunctionParametersParser
-{
-
-	private ParserState currentState;
-
-	private String params;
-
-	private List parameters;
-
-	private StringBuffer currentParameter;
-
-	private abstract class ParserState
-	{
-		protected ParserState previousState;
-
-		public ParserState(ParserState previousState) {
-			this.previousState = previousState;
-		}
-
-		public abstract void processCharacter(char c);
-	}
-
-	private class ParserStateInList
-		extends ParserState
-	{
-
-		public ParserStateInList(ParserState previousState) {
-			super(previousState);
-		}
-
-		public void processCharacter(char c) {
-			switch (c) {
-				case '|':
-					parameters.add(currentParameter.toString());
-					currentParameter = new StringBuffer();
-					break;
-
-				case '\\':
-					currentState = new ParserStateInEscapedCharacter(this);
-					break;
-
-				default:
-					currentParameter.append(c);
-					break;
-			}
-		}
-	}
-
-	private class ParserStateInEscapedCharacter
-		extends ParserState
-	{
-
-		public ParserStateInEscapedCharacter(ParserState previousState) {
-			super(previousState);
-		}
-
-		public void processCharacter(char c) {
-			//In all cases we have to return to the previous state
-			currentState = previousState;
-
-			switch (c) {
-				case '\\':
-					currentParameter.append(c);
-					break;
-
-				case '|':
-					currentParameter.append(c);
-					break;
-
-				default:
-					//Invalid character escaped...
-					break;
-			}
-		}
-	}
-
-	private JSFunctionParametersParser(String params) {
-		this.params = params;
-	}
-
-	private void parse() {
-		parameters = new ArrayList();
-		currentState = new ParserStateInList(null);
-		currentParameter = new StringBuffer();
-
-		for (int i = 0; i < params.length(); i++) {
-			char c = params.charAt(i);
-			currentState.processCharacter(c);
-		}
-		parameters.add(currentParameter.toString());
-	}
-
-	public static List parse(String params) {
-		JSFunctionParametersParser parser = new JSFunctionParametersParser(params);
-		parser.parse();
-		return parser.parameters;
-	}
-
-}
diff --git a/com/aelitis/azureus/util/LoginInfoManager.java b/com/aelitis/azureus/util/LoginInfoManager.java
deleted file mode 100644
index 55ca7fd..0000000
--- a/com/aelitis/azureus/util/LoginInfoManager.java
+++ /dev/null
@@ -1,202 +0,0 @@
-package com.aelitis.azureus.util;
-
-import java.util.Iterator;
-import java.util.Map;
-
-import org.gudy.azureus2.core3.util.UrlUtils;
-
-import com.aelitis.azureus.core.crypto.VuzeCryptoException;
-import com.aelitis.azureus.core.crypto.VuzeCryptoManager;
-import com.aelitis.azureus.core.util.CopyOnWriteList;
-
-/**
- * A manager class to store login info
- * <P>
- * Users can add <code>ILoginInfoListener</code>'s to be notified when any login event occurs
- * 
- * @author knguyen
- *
- */
-public class LoginInfoManager
-{
-	private static final String NAME_NOT_SET_VALUE = "no.user.name.has.been.set";
-
-	private static LoginInfoManager INSTANCE;
-
-	/*
-	 * DO NOT initialize userName and userID to null because null is a valid value for these variables
-	 */
-	private String userName = NAME_NOT_SET_VALUE;
-
-	private String displayName = null;
-
-	private String pk = null;
-
-	private boolean isRegistrationStillOpen = false;
-	
-	private CopyOnWriteList listeners = new CopyOnWriteList();
-
-	private String avatarURL;
-
-	private LoginInfoManager() {
-		//Making this private
-	}
-
-	public static LoginInfoManager getInstance() {
-		if (null == INSTANCE) {
-			INSTANCE = new LoginInfoManager();
-		}
-		return INSTANCE;
-	}
-
-	/**
-	 * Adds the given <code>IRuntimeInfoListener</code> to the list of listeners for login info
-	 * @param listener
-	 */
-	public void addListener(ILoginInfoListener listener) {
-		if (false == listeners.contains(listener)) {
-			listeners.add(listener);
-			
-			if (isLoggedIn()) {
-				listener.loginUpdate(new LoginInfo(), true);
-
-				if (avatarURL != null) {
-					listener.avatarURLUpdated(avatarURL);
-				}
-			}
-		}
-
-	}
-
-	/**
-	 * Removes the given <code>IRuntimeInfoListener</code> from the list of listeners for login info
-	 * @param infoType
-	 * @param listener
-	 */
-	public void removeListener(ILoginInfoListener listener) {
-		listeners.remove(listener);
-	}
-
-	public LoginInfo getUserInfo() {
-		return new LoginInfo();
-	}
-
-	public void setUserInfo(String userName, String displayName, String pk, String avatarURL) {
-		boolean changed = false;
-		boolean isNewLoginID = false;
-		if (!("" + userName).equals("" + this.userName)) {
-			this.userName = userName;
-			changed = true;
-			isNewLoginID = true;
-		}
-		if (!("" + displayName).equals("" + this.displayName)) {
-			this.displayName = displayName;
-			changed = true;
-		}
-		if (!("" + pk).equals("" + this.pk)) {
-			this.pk = pk;
-			changed = true;
-		}
-		if (!("" + avatarURL).equals("" + this.avatarURL)) {
-			setAvatarURL(avatarURL);
-			changed = true;
-		}
-
-		if (changed) {
-			notifyListeners(isNewLoginID);
-		}
-	}
-	
-	public void setAvatarURL(String avatarURL) {
-		if (avatarURL == null) {
-			return;
-		}
-		if (avatarURL.equals(this.avatarURL)) {
-			return;
-		}
-		this.avatarURL = avatarURL;
-		
-		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
-			((ILoginInfoListener) iterator.next()).avatarURLUpdated(avatarURL);
-		}
-	}
-
-	public boolean isLoggedIn() {
-		return this.userName != null && !this.userName.equals(NAME_NOT_SET_VALUE);
-	}
-
-	private void notifyListeners(boolean isNewLoginID) {
-
-		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
-			((ILoginInfoListener) iterator.next()).loginUpdate(new LoginInfo(),
-					isNewLoginID);
-		}
-
-	}
-
-	public class LoginInfo
-	{
-		public final String userName = LoginInfoManager.this.userName;
-
-		public final String displayName = LoginInfoManager.this.displayName == null
-				? LoginInfoManager.this.userName : LoginInfoManager.this.displayName;
-
-		public final boolean isRegistrationStillOpen = LoginInfoManager.this.isRegistrationStillOpen;
-		
-		/**
-		 * The public key that the webapp thinks we have
-		 */
-		public final String pk = LoginInfoManager.this.pk;
-		
-		public final String avatarUrl = LoginInfoManager.this.avatarURL;
-
-		public String getProfileAHREF(String referer) {
-			StringBuffer buf = new StringBuffer();
-			buf.append("<A HREF=\"");
-			buf.append( ConstantsVuze.getDefaultContentNetwork().getProfileService(userName, referer ));
-			buf.append("\" TITLE=\"");
-			buf.append(displayName);
-			if (!displayName.equals(userName)) {
-				buf.append(" (");
-				buf.append(userName);
-				buf.append(")");
-			}
-			buf.append("\">");
-			buf.append(displayName);
-			buf.append("</A>");
-			return buf.toString();
-		}
-	}
-
-	/**
-	 * @param mapUserInfo
-	 *
-	 * @since 3.1.0.1
-	 */
-	public void setUserInfo(Map mapUserInfo) {
-		try {
-			setUserInfo(MapUtils.getMapString(mapUserInfo, "login-id", null),
-					MapUtils.getMapString(mapUserInfo, "display-name", null),
-					VuzeCryptoManager.getSingleton().getPublicKey(""),
-					MapUtils.getMapString(mapUserInfo, "avatar.url", null));
-		} catch (VuzeCryptoException e) {
-		}
-	}
-
-	/**
-	 * @param b
-	 *
-	 * @since 4.0.0.5
-	 */
-	public void logout() {
-		this.userName = null;
-		this.displayName = null;
-		this.avatarURL = null;
-		this.pk = null;
-		notifyListeners(false);
-		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
-			((ILoginInfoListener) iterator.next()).avatarURLUpdated(avatarURL);
-		}
-	}
-
-}
diff --git a/com/aelitis/azureus/util/NavigationHelper.java b/com/aelitis/azureus/util/NavigationHelper.java
index e0a95aa..7caa1cd 100644
--- a/com/aelitis/azureus/util/NavigationHelper.java
+++ b/com/aelitis/azureus/util/NavigationHelper.java
@@ -31,17 +31,12 @@ import com.aelitis.azureus.core.vuzefile.VuzeFile;
 import com.aelitis.azureus.core.vuzefile.VuzeFileComponent;
 import com.aelitis.azureus.core.vuzefile.VuzeFileHandler;
 import com.aelitis.azureus.core.vuzefile.VuzeFileProcessor;
-import com.aelitis.azureus.ui.skin.SkinConstants;
 
 public class 
 NavigationHelper 
 {
 	public static final int COMMAND_SWITCH_TO_TAB	= 1;
 	public static final int COMMAND_CONDITION_CHECK	= 2;
-	public static final int COMMAND_BUDDY_SYNC	= 3;
-	
-	public static final String COMMAND_CHECK_BUDDY_MANAGER			= "buddy-manager";
-	public static final String COMMAND_CHECK_BUDDY_MANAGER_ENABLED	= "enabled";
 	
 		
 	private static CopyOnWriteList	listeners = new CopyOnWriteList();
@@ -244,9 +239,6 @@ NavigationHelper
 			
 			List	l_args3 = new ArrayList();
 			
-			l_args3.add( COMMAND_CHECK_BUDDY_MANAGER );
-			l_args3.add( COMMAND_CHECK_BUDDY_MANAGER_ENABLED );
-			
 			command3.put( "type", new Long( COMMAND_CONDITION_CHECK ));
 			command3.put( "args", l_args3 );
 			
diff --git a/com/aelitis/azureus/util/PlayUtils.java b/com/aelitis/azureus/util/PlayUtils.java
index 0c19528..1dea0bb 100644
--- a/com/aelitis/azureus/util/PlayUtils.java
+++ b/com/aelitis/azureus/util/PlayUtils.java
@@ -31,7 +31,6 @@ import org.gudy.azureus2.core3.logging.LogIDs;
 import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.torrent.TOTorrentException;
-import org.gudy.azureus2.core3.torrent.TOTorrentFile;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl;
 
@@ -40,8 +39,6 @@ import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.download.DownloadManagerEnhancer;
 import com.aelitis.azureus.core.download.EnhancedDownloadManager;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContent;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentV3;
 
 import org.gudy.azureus2.plugins.PluginInterface;
@@ -60,6 +57,8 @@ public class PlayUtils
 	private static boolean triedLoadingEmpPluginClass = false;
 
 	private static Method methodIsExternallyPlayable;
+
+	private static PluginInterface piEmp;
 	
 	//private static Method methodIsExternalPlayerInstalled;
 
@@ -286,19 +285,25 @@ public class PlayUtils
 	}*/
 	
 	private static synchronized final boolean loadEmpPluginClass() {
+		if (piEmp != null && piEmp.getPluginState().isUnloaded()) {
+			piEmp = null;
+			triedLoadingEmpPluginClass = false;
+			methodIsExternallyPlayable = null;
+		}
+
 		if (!triedLoadingEmpPluginClass) {
 			triedLoadingEmpPluginClass = true;
 
   		try {
-  			PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
+  			piEmp = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
   					"azemp");
   
-  			if (pi == null) {
+  			if (piEmp == null) {
   
   				return (false);
   			}
   
-  			Class empPluginClass = pi.getPlugin().getClass();
+  			Class empPluginClass = piEmp.getPlugin().getClass();
 
   			methodIsExternallyPlayable = empPluginClass.getMethod("isExternallyPlayabale", new Class[] {
   				TOTorrent.class
diff --git a/com/aelitis/azureus/util/PublishUtils.java b/com/aelitis/azureus/util/PublishUtils.java
deleted file mode 100644
index 3c23546..0000000
--- a/com/aelitis/azureus/util/PublishUtils.java
+++ /dev/null
@@ -1,165 +0,0 @@
-package com.aelitis.azureus.util;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.util.Debug;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.torrent.Torrent;
-
-import org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl;
-import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentImpl;
-
-/**
- * Publish functions that are used by both the Publisher plugin and AZ3ui's publish window
- * 
- * @author TuxPaper
- *
- */
-public class PublishUtils
-{
-	private static final String CONTENTMAP_KEY = "Plugin.azdirector.ContentMap";
-
-	private static final String COMPLETE_ATTRIBUTE_KEY 	= "COMPLETE";
-
-	public static final String PUBLISH_ATTRIBUTE_KEY = "DIRECTOR PUBLISH";
-
-	public static boolean isPublished(DownloadManager dm) {
-		if (dm == null) {
-			return false;
-		}
-		try {
-			Map mapAttr = dm.getDownloadState().getMapAttribute(CONTENTMAP_KEY);
-
-			return mapAttr != null
-					&& mapAttr.containsKey(PublishUtils.PUBLISH_ATTRIBUTE_KEY);
-		} catch (Exception e) {
-			Debug.out("baH", e);
-		}
-		return false;
-	}
-
-	/**
-	 * @param download
-	 * @return
-	 *
-	 * @since 3.0.1.5
-	 */
-	public static boolean isPublished(Download download) {
-		if (download instanceof DownloadImpl) {
-			return isPublished(((DownloadImpl) download).getDownload());
-		}
-		return false;
-	}
-
-	public static void setPublished(Torrent torrent) {
-		if (torrent instanceof TorrentImpl) {
-			setPublished(((TorrentImpl) torrent).getTorrent());
-		}
-	}
-
-	/**
-	 * @param torrent
-	 *
-	 * @since 3.0.1.5
-	 */
-	public static void setPublished(TOTorrent torrent) {
-		try {
-			if (torrent == null) {
-				return;
-			}
-
-			Map map = torrent.getAdditionalMapProperty("attributes");
-
-			if (map != null) {
-				Map mapAttr = (Map) map.get(CONTENTMAP_KEY);
-
-				mapAttr.put(PublishUtils.PUBLISH_ATTRIBUTE_KEY, new Long(1));
-			}
-		} catch (Exception e) {
-			Debug.out("baH", e);
-		}
-	}
-
-	public static void setPublished(DownloadManager dm, boolean isPublishedContent) {
-		if (isPublishedContent) {
-			setPublished(dm);
-			return;
-		}
-		
-		try {
-			Map mapAttr = dm.getDownloadState().getMapAttribute(CONTENTMAP_KEY);
-
-			if (mapAttr == null) {
-				return;
-			}
-			mapAttr = new HashMap(mapAttr);
-			Object remove = mapAttr.remove(PublishUtils.PUBLISH_ATTRIBUTE_KEY);
-			if (remove != null) {
-				dm.getDownloadState().setMapAttribute(CONTENTMAP_KEY, mapAttr);
-			}
-		} catch (Exception e) {
-			Debug.out(e);
-		}
-	}
-
-	public static void setPublished(DownloadManager dm) {
-		try {
-			Map mapAttr = dm.getDownloadState().getMapAttribute(CONTENTMAP_KEY);
-
-			if (mapAttr == null) {
-				mapAttr = new HashMap();
-			} else {
-				mapAttr = new HashMap(mapAttr);
-			}
-			mapAttr.put(PublishUtils.PUBLISH_ATTRIBUTE_KEY, new Long(1));
-			dm.getDownloadState().setMapAttribute(CONTENTMAP_KEY, mapAttr);
-		} catch (Exception e) {
-			Debug.out("baH", e);
-		}
-	}
-
-	public static void setPublished(Download download) {
-		if (download instanceof DownloadImpl) {
-			setPublished(((DownloadImpl) download).getDownload());
-		}
-	}
-
-	public static void setPublishComplete(DownloadManager dm) {
-		try {
-			Map mapAttr = dm.getDownloadState().getMapAttribute(CONTENTMAP_KEY);
-
-			if ( mapAttr == null ){
-				
-				mapAttr = new HashMap();
-			}else{
-				mapAttr = new HashMap(mapAttr);
-			}
-			
-			mapAttr.put( COMPLETE_ATTRIBUTE_KEY, new Long(1));
-			
-			dm.getDownloadState().setMapAttribute(CONTENTMAP_KEY, mapAttr);
-			
-		} catch (Exception e) {
-			
-			Debug.out("baH", e);
-		}
-	}
-
-	public static boolean isPublishComplete( DownloadManager dm ){
-		
-		Map mapAttr = dm.getDownloadState().getMapAttribute(CONTENTMAP_KEY);
-
-		if ( mapAttr == null ){
-			
-			return( false );
-		}
-		
-		Long complete = (Long)mapAttr.get( COMPLETE_ATTRIBUTE_KEY );
-
-		return( complete != null );
-	}
-}
diff --git a/com/aelitis/net/magneturi/MagnetURIHandler.java b/com/aelitis/net/magneturi/MagnetURIHandler.java
index dfcd3c4..c17e0bb 100644
--- a/com/aelitis/net/magneturi/MagnetURIHandler.java
+++ b/com/aelitis/net/magneturi/MagnetURIHandler.java
@@ -22,6 +22,8 @@
 
 package com.aelitis.net.magneturi;
 
+import java.net.URL;
+
 import com.aelitis.net.magneturi.impl.MagnetURIHandlerImpl;
 
 /**
@@ -53,4 +55,21 @@ MagnetURIHandler
 	addInfo(
 		String		name,
 		int			info );
+	
+	public abstract URL
+	registerResource(
+		ResourceProvider		provider );
+	
+	public interface
+	ResourceProvider
+	{
+		public String
+		getUID();
+		
+		public String
+		getFileType();
+				
+		public byte[]
+		getData();
+	}
 }
diff --git a/com/aelitis/net/magneturi/impl/MagnetURIHandlerImpl.java b/com/aelitis/net/magneturi/impl/MagnetURIHandlerImpl.java
index c5e41a0..dfd0bdd 100644
--- a/com/aelitis/net/magneturi/impl/MagnetURIHandlerImpl.java
+++ b/com/aelitis/net/magneturi/impl/MagnetURIHandlerImpl.java
@@ -22,29 +22,18 @@
 
 package com.aelitis.net.magneturi.impl;
 
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.URL;
-import java.net.URLDecoder;
+import java.io.*;
+import java.net.*;
 import java.util.*;
 
 import org.bouncycastle.util.encoders.Base64;
 import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.logging.*;
+import org.gudy.azureus2.core3.logging.LogEvent;
+import org.gudy.azureus2.core3.logging.LogIDs;
+import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.util.*;
 
-import com.aelitis.azureus.core.util.CaseSensitiveFileMap;
+import com.aelitis.azureus.core.util.HTTPUtils;
 import com.aelitis.azureus.core.util.png.PNG;
 import com.aelitis.net.magneturi.MagnetURIHandler;
 import com.aelitis.net.magneturi.MagnetURIHandlerListener;
@@ -97,6 +86,8 @@ MagnetURIHandlerImpl
 	
 	private Map		info_map 	= new HashMap();
 	
+	private Map<String,ResourceProvider>	resources = new HashMap<String, ResourceProvider>();
+	
 	protected
 	MagnetURIHandlerImpl()
 	{
@@ -150,11 +141,10 @@ MagnetURIHandlerImpl
 								
 								errors	= 0;
 								
-								Thread t = 
-									new AEThread( "MagnetURIHandler:processor" )
+								new AEThread2( "MagnetURIHandler:processor",true)
 									{
 										public void
-										runSupport()
+										run()
 										{
 											boolean	close_socket	= true;
 											
@@ -243,11 +233,8 @@ MagnetURIHandlerImpl
 												}
 											}
 										}
-									};
-								
-								t.setDaemon( true );
+									}.start();
 								
-								t.start();
 								
 							}catch( Throwable e ){
 								
@@ -283,10 +270,10 @@ MagnetURIHandlerImpl
 		
 			// magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C
 		
-		Map		original_params 			= new HashMap();
-		Map		lc_params					= new HashMap();
+		Map<String,String>		original_params 			= new HashMap<String,String>();
+		Map<String,String>		lc_params					= new HashMap<String,String>();
 		
-		List 	source_params	= new ArrayList();
+		List<String> 	source_params	= new ArrayList<String>();
 		
 		int	pos	= get.indexOf( '?' );
 		
@@ -845,6 +832,34 @@ MagnetURIHandlerImpl
 
 			
 			writeReply( os, "application/x-javascript", script );
+			
+		}else if ( get.startsWith( "/resource." )){
+
+			String rid = lc_params.get( "rid" );
+			
+			ResourceProvider provider;
+			
+			synchronized( resources ){
+				
+				provider = resources.get( rid );
+			}
+			
+			if ( provider != null ){
+				
+				byte[] data = provider.getData();
+				
+				if ( data != null ){
+				
+					writeReply( os, HTTPUtils.guessContentTypeFromFileType( provider.getFileType()), data );
+					
+				}else{
+					
+					writeNotFound( os );
+				}
+			}else{
+				
+				writeNotFound( os );
+			}
 		}
 		
 		return( true );
@@ -1024,4 +1039,26 @@ MagnetURIHandlerImpl
 			
 		}
 	}
+	
+	public URL
+	registerResource(
+		ResourceProvider		provider )
+	{
+		try{
+			String rid = URLEncoder.encode( provider.getUID(), "UTF-8" );
+
+			synchronized( resources ){
+						
+				resources.put( rid, provider );
+			}				
+			
+			return( new URL( "http://127.0.0.1:" + port +  "/resource." + provider.getFileType() + "?rid=" + rid ));
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+			
+			return( null );
+		}
+	}
 }
diff --git a/com/aelitis/net/natpmp/upnp/impl/NatPMPUPnPRootDeviceImpl.java b/com/aelitis/net/natpmp/upnp/impl/NatPMPUPnPRootDeviceImpl.java
index d857ee1..03d8b08 100644
--- a/com/aelitis/net/natpmp/upnp/impl/NatPMPUPnPRootDeviceImpl.java
+++ b/com/aelitis/net/natpmp/upnp/impl/NatPMPUPnPRootDeviceImpl.java
@@ -25,6 +25,7 @@ package com.aelitis.net.natpmp.upnp.impl;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.URL;
+import java.util.Map;
 
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.ThreadPool;
@@ -125,6 +126,12 @@ NatPMPUPnPRootDeviceImpl
 		return( false );
 	}
 	
+	public Map
+	getDiscoveryCache() 
+	{
+		return( null );
+	}
+	
 	public void
 	addListener(
 		UPnPRootDeviceListener	l )
diff --git a/com/aelitis/net/upnp/UPnP.java b/com/aelitis/net/upnp/UPnP.java
index bf7f0ab..06cde24 100644
--- a/com/aelitis/net/upnp/UPnP.java
+++ b/com/aelitis/net/upnp/UPnP.java
@@ -22,6 +22,8 @@
 
 package com.aelitis.net.upnp;
 
+import java.util.Map;
+
 /**
  * @author parg
  *
@@ -52,6 +54,10 @@ UPnP
 	search(
 		String[]		STs );
 	
+	public void
+	injectDiscoveryCache(
+		Map				cache );
+	
 		/**
 		 * Logs a message to all registered log listeners
 		 * @param str
diff --git a/com/aelitis/net/upnp/UPnPRootDevice.java b/com/aelitis/net/upnp/UPnPRootDevice.java
index e96bc0f..9566391 100644
--- a/com/aelitis/net/upnp/UPnPRootDevice.java
+++ b/com/aelitis/net/upnp/UPnPRootDevice.java
@@ -25,6 +25,7 @@ package com.aelitis.net.upnp;
 import java.net.NetworkInterface;
 import java.net.URL;
 import java.net.InetAddress;
+import java.util.Map;
 
 
 /**
@@ -59,6 +60,9 @@ UPnPRootDevice
 	public boolean
 	isDestroyed();
 	
+	public Map
+	getDiscoveryCache();
+	
 	public void
 	addListener(
 		UPnPRootDeviceListener	l );
diff --git a/com/aelitis/net/upnp/UPnPSSDP.java b/com/aelitis/net/upnp/UPnPSSDP.java
index 7039b31..cda3fea 100644
--- a/com/aelitis/net/upnp/UPnPSSDP.java
+++ b/com/aelitis/net/upnp/UPnPSSDP.java
@@ -27,7 +27,6 @@ UPnPSSDP
 {
 	public static final String				SSDP_GROUP_ADDRESS 	= "239.255.255.250"; 
 	public static final int					SSDP_GROUP_PORT		= 1900;	
-	public static final int					SSDP_CONTROL_PORT	= 0; // 8008;
 
 	public int
 	getControlPort();
diff --git a/com/aelitis/net/upnp/impl/UPnPImpl.java b/com/aelitis/net/upnp/impl/UPnPImpl.java
index 46062c7..8fea659 100644
--- a/com/aelitis/net/upnp/impl/UPnPImpl.java
+++ b/com/aelitis/net/upnp/impl/UPnPImpl.java
@@ -37,6 +37,7 @@ import org.gudy.azureus2.core3.util.AEMonitor;
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.FileUtil;
+import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.core3.util.ThreadPool;
 import org.gudy.azureus2.core3.util.TorrentUtils;
 
@@ -104,6 +105,8 @@ UPnPImpl
 	private ThreadPool	device_dispatcher	 = new ThreadPool("UPnPDispatcher", 1, true );
 	private Set			device_dispatcher_pending	= new HashSet();
 	
+	private Map<String,long[]>	failed_urls = new HashMap<String,long[]>();
+	
 	protected AEMonitor	this_mon 	= new AEMonitor( "UPnP" );
 
 	protected
@@ -122,6 +125,35 @@ UPnPImpl
 		ssdp.start();
 	}
 	
+	public void 
+	injectDiscoveryCache(
+		Map 		cache )
+	{
+		try{
+			String	ni_s	= new String((byte[])cache.get( "ni" ), "UTF-8" );
+			String	la_s 	= new String((byte[])cache.get( "la" ), "UTF-8" );
+			String	usn 	= new String((byte[])cache.get( "usn" ), "UTF-8" );
+			String	loc_s 	= new String((byte[])cache.get( "loc" ), "UTF-8" );
+			
+			NetworkInterface	network_interface = NetworkInterface.getByName( ni_s );
+			
+			if ( network_interface == null ){
+				
+				return;
+			}
+			
+			InetAddress	local_address = InetAddress.getByName( la_s );
+			
+			URL location = new URL( loc_s );
+			
+			rootDiscovered( network_interface, local_address, usn, location );
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+	}
+	
 	public void
 	rootDiscovered(
 		final NetworkInterface		network_interface,
@@ -539,28 +571,105 @@ UPnPImpl
 	
 		throws UPnPException
 	{
-		try{
+		String url_str = url.toExternalForm();
+
+		boolean	record_failure = true;
+		
+		try{			
 			TorrentUtils.setTLSDescription( "UPnP Device" + ( friendly_name==null?"":( ": " + friendly_name )));
 			
 			ResourceDownloaderFactory rdf = adapter.getResourceDownloaderFactory();
 				
-			ResourceDownloader rd = rdf.getRetryDownloader( rdf.create( url, true ), 3 );
+			int	retries;
+			
+			synchronized( failed_urls ){
+
+				long[] fails = failed_urls.get( url_str );
+				
+				if ( fails == null ){
+					
+					retries = 3;
+					
+				}else{
+					
+					long	consec_fails 	= fails[0];
+					long	last_fail		= fails[1];
+					
+					long	max_period	= 10*60*1000;
+					long	period 		= 60*1000;
+					
+					for (int i=0;i<consec_fails;i++){
+						
+						period <<= 1;
+						
+						if ( period >= max_period ){
+							
+							period = max_period;
+							
+							break;
+						}
+					}
+					
+					if ( SystemTime.getMonotonousTime() - last_fail < period ){
+						
+						record_failure = false;
+						
+						throw( new UPnPException( "Download failed too recently, ignoring" ));
+					}
+					
+					retries = 1;
+				}
+			}
+			
+			ResourceDownloader rd = rdf.getRetryDownloader( rdf.create( url, true ), retries );
 				
 			rd.addListener( this );
 				
 			InputStream	data = rd.download();
-					
+						
 			try{
-				return( parseXML( data ));
+				
+				SimpleXMLParserDocument res = parseXML( data );
+			
+				synchronized( failed_urls ){
 					
+					failed_urls.remove( url_str );
+				}
+				
+				return( res );
+				
 			}finally{
 					
 				data.close();
-			}
+			}	
 		}catch( Throwable e ){
 				
-			adapter.log( Debug.getNestedExceptionMessageAndStack(e));
-
+			if ( record_failure ){
+				
+				synchronized( failed_urls ){
+					
+					if ( failed_urls.size() >= 64 ){
+						
+						failed_urls.clear();
+					}
+					
+					long[] fails = failed_urls.get( url_str );
+					
+					if ( fails == null ){
+						
+						fails = new long[2];
+						
+						failed_urls.put( url_str, fails );
+					}
+					
+					fails[0]++;
+					
+					fails[1] = SystemTime.getMonotonousTime();
+				}
+			
+				adapter.log( Debug.getNestedExceptionMessageAndStack(e));
+			}
+			
 			if (e instanceof UPnPException ){
 				
 				throw((UPnPException)e);
@@ -640,147 +749,154 @@ UPnPImpl
 	
 		throws SimpleXMLParserDocumentException, UPnPException, IOException
 	{
+		//long	start = SystemTime.getMonotonousTime();
+
 		URL	control = service.getControlURL();
-		
-		adapter.trace( "UPnP:Request: -> " + control + "," + request );
 
-		if ( use_http_connection ){
-			
-			try{
-				TorrentUtils.setTLSDescription( "UPnP Device: " + service.getDevice().getFriendlyName());
-			
-				HttpURLConnection	con1 = (HttpURLConnection)Java15Utils.openConnectionForceNoProxy(control);
-					
-				con1.setRequestProperty( "SOAPAction", "\""+ soap_action + "\"");
-					
-				con1.setRequestProperty( "Content-Type", "text/xml; charset=\"utf-8\"" );
-					
-				con1.setRequestProperty( "User-Agent", "Azureus (UPnP/1.0)" );
-					
-				con1.setRequestMethod( "POST" );
-					
-				con1.setDoInput( true );
-				con1.setDoOutput( true );
-					
-				OutputStream	os = con1.getOutputStream();
-					
-				PrintWriter	pw = new PrintWriter( new OutputStreamWriter(os, "UTF-8" ));
-								
-				pw.println( request );
-					
-				pw.flush();
-			
-				con1.connect();
-					
-				if ( con1.getResponseCode() == 405 || con1.getResponseCode() == 500 ){
+		try{		
+			adapter.trace( "UPnP:Request: -> " + control + "," + request );
+	
+			if ( use_http_connection ){
+				
+				try{
+					TorrentUtils.setTLSDescription( "UPnP Device: " + service.getDevice().getFriendlyName());
+				
+					HttpURLConnection	con1 = (HttpURLConnection)Java15Utils.openConnectionForceNoProxy(control);
 						
-						// gotta retry with M-POST method
+					con1.setRequestProperty( "SOAPAction", "\""+ soap_action + "\"");
 						
-					try{
-						HttpURLConnection con2 = (HttpURLConnection)control.openConnection();
-							
-						con2.setRequestProperty( "Content-Type", "text/xml; charset=\"utf-8\"" );
-							
-						con2.setRequestMethod( "M-POST" );
-							
-						con2.setRequestProperty( "MAN", "\"http://schemas.xmlsoap.org/soap/envelope/\"; ns=01" );
+					con1.setRequestProperty( "Content-Type", "text/xml; charset=\"utf-8\"" );
+						
+					con1.setRequestProperty( "User-Agent", "Azureus (UPnP/1.0)" );
+						
+					con1.setRequestMethod( "POST" );
+						
+					con1.setDoInput( true );
+					con1.setDoOutput( true );
+						
+					OutputStream	os = con1.getOutputStream();
+						
+					PrintWriter	pw = new PrintWriter( new OutputStreamWriter(os, "UTF-8" ));
+									
+					pw.println( request );
+						
+					pw.flush();
 				
-						con2.setRequestProperty( "01-SOAPACTION", "\""+ soap_action + "\"");
+					con1.connect();
+						
+					if ( con1.getResponseCode() == 405 || con1.getResponseCode() == 500 ){
 							
-						con2.setDoInput( true );
-						con2.setDoOutput( true );
+							// gotta retry with M-POST method
 							
-						os = con2.getOutputStream();
+						try{
+							HttpURLConnection con2 = (HttpURLConnection)control.openConnection();
+								
+							con2.setRequestProperty( "Content-Type", "text/xml; charset=\"utf-8\"" );
+								
+							con2.setRequestMethod( "M-POST" );
+								
+							con2.setRequestProperty( "MAN", "\"http://schemas.xmlsoap.org/soap/envelope/\"; ns=01" );
+					
+							con2.setRequestProperty( "01-SOAPACTION", "\""+ soap_action + "\"");
+								
+							con2.setDoInput( true );
+							con2.setDoOutput( true );
+								
+							os = con2.getOutputStream();
+								
+							pw = new PrintWriter( new OutputStreamWriter(os, "UTF-8" ));
+											
+							pw.println( request );
+								
+							pw.flush();
+					
+							con2.connect();
 							
-						pw = new PrintWriter( new OutputStreamWriter(os, "UTF-8" ));
-										
-						pw.println( request );
+							return( parseXML(con2.getInputStream()));	
 							
-						pw.flush();
-				
-						con2.connect();
+						}catch( Throwable e ){
+							
+						}
 						
-						return( parseXML(con2.getInputStream()));	
+						InputStream es = con1.getErrorStream();
 						
-					}catch( Throwable e ){
+						String	info = null;
 						
-					}
-					
-					InputStream es = con1.getErrorStream();
-					
-					String	info = null;
-					
-					try{
-						info = FileUtil.readInputStreamAsString( es, 512 );
+						try{
+							info = FileUtil.readInputStreamAsString( es, 512 );
+							
+						}catch( Throwable e ){
+						}
 						
-					}catch( Throwable e ){
-					}
-					
-					String error = "SOAP RPC failed: " + con1.getResponseCode() + " " + con1.getResponseMessage();
-					
-					if ( info != null ){
+						String error = "SOAP RPC failed: " + con1.getResponseCode() + " " + con1.getResponseMessage();
 						
-						error += " - " + info;
+						if ( info != null ){
+							
+							error += " - " + info;
+						}
+	
+						throw( new IOException ( error ));
+						
+					}else{
+							
+						return( parseXML(con1.getInputStream()));
 					}
-
-					throw( new IOException ( error ));
+				}finally{
 					
-				}else{
-						
-					return( parseXML(con1.getInputStream()));
+					TorrentUtils.setTLSDescription( null );
 				}
-			}finally{
+			}else{
+				final int CONNECT_TIMEOUT 	= 15*1000;
+				final int READ_TIMEOUT		= 30*1000;
 				
-				TorrentUtils.setTLSDescription( null );
-			}
-		}else{
-			final int CONNECT_TIMEOUT 	= 15*1000;
-			final int READ_TIMEOUT		= 30*1000;
-			
-			Socket	socket = new Socket();
-			
-			socket.connect( new InetSocketAddress( control.getHost(), control.getPort()), CONNECT_TIMEOUT );
-			
-			socket.setSoTimeout( READ_TIMEOUT );
-				
-			try{
-				PrintWriter	pw = new PrintWriter(new OutputStreamWriter( socket.getOutputStream(), "UTF8" ));
-
-				String	url_target = control.toString();
-			
-				int	p1 	= url_target.indexOf( "://" ) + 3;
-				p1		= url_target.indexOf( "/", p1 );
+				Socket	socket = new Socket( Proxy.NO_PROXY );
 				
-				url_target = url_target.substring( p1 );
+				socket.connect( new InetSocketAddress( control.getHost(), control.getPort()), CONNECT_TIMEOUT );
 				
-				pw.print( "POST " + url_target + " HTTP/1.1" + NL );
-				pw.print( "Content-Type: text/xml; charset=\"utf-8\"" + NL );
-				pw.print( "SOAPAction: \"" + soap_action + "\"" + NL );
-				pw.print( "User-Agent: Azureus (UPnP/1.0)" + NL );
-				pw.print( "Host: " + control.getHost() + NL );
-				pw.print( "Content-Length: " + request.getBytes( "UTF8" ).length + NL );
-				pw.print( "Connection: Keep-Alive" + NL );
-				pw.print( "Pragma: no-cache" + NL + NL );
+				socket.setSoTimeout( READ_TIMEOUT );
+					
+				try{
+					PrintWriter	pw = new PrintWriter(new OutputStreamWriter( socket.getOutputStream(), "UTF8" ));
 	
-				pw.print( request );
+					String	url_target = control.toString();
 				
-				pw.flush();
-				
-				InputStream	is = HTTPUtils.decodeChunkedEncoding( socket );
-				
-				return( parseXML( is ));
-				
-			}finally{
-
-				try{
-					socket.close();
+					int	p1 	= url_target.indexOf( "://" ) + 3;
+					p1		= url_target.indexOf( "/", p1 );
+					
+					url_target = url_target.substring( p1 );
+					
+					pw.print( "POST " + url_target + " HTTP/1.1" + NL );
+					pw.print( "Content-Type: text/xml; charset=\"utf-8\"" + NL );
+					pw.print( "SOAPAction: \"" + soap_action + "\"" + NL );
+					pw.print( "User-Agent: Azureus (UPnP/1.0)" + NL );
+					pw.print( "Host: " + control.getHost() + NL );
+					pw.print( "Content-Length: " + request.getBytes( "UTF8" ).length + NL );
+					pw.print( "Connection: Keep-Alive" + NL );
+					pw.print( "Pragma: no-cache" + NL + NL );
+		
+					pw.print( request );
+					
+					pw.flush();
+					
+					InputStream	is = HTTPUtils.decodeChunkedEncoding( socket );
 					
-				}catch( Throwable e ){
+					return( parseXML( is ));
 					
-					Debug.printStackTrace(e);
+				}finally{
+	
+					try{
+						socket.close();
+						
+					}catch( Throwable e ){
+						
+						Debug.printStackTrace(e);
+					}
 				}
-			}
-		} 
+			} 
+		}finally{
+		
+			//System.out.println( "UPnP: invocation of " + control + "/" + soap_action + " took " + ( SystemTime.getMonotonousTime() - start ));
+		}
 	}
 	
 	protected File
diff --git a/com/aelitis/net/upnp/impl/device/UPnPRootDeviceImpl.java b/com/aelitis/net/upnp/impl/device/UPnPRootDeviceImpl.java
index 539e23b..24ebd44 100644
--- a/com/aelitis/net/upnp/impl/device/UPnPRootDeviceImpl.java
+++ b/com/aelitis/net/upnp/impl/device/UPnPRootDeviceImpl.java
@@ -58,12 +58,13 @@ UPnPRootDeviceImpl
 			//true,		// report always	removed, apparently it works OK now according to manufacturer
 		};
 	
-	private UPnPImpl			upnp;
-	private NetworkInterface	network_interface;
-	private InetAddress			local_address;
+	final private UPnPImpl			upnp;
+	final private NetworkInterface	network_interface;
+	final private InetAddress		local_address;
+	
+	final private String		usn;
+	final private URL			location;
 	
-	private String		usn;
-	private URL			location;
 	private URL			url_base_for_relative_urls;
 	private URL			saved_url_base_for_relative_urls;
 	
@@ -140,6 +141,27 @@ UPnPRootDeviceImpl
 		}
 	}
 	
+	public Map 
+	getDiscoveryCache() 
+	{		
+		try{
+			Map	cache = new HashMap();
+
+			cache.put( "ni", network_interface.getName().getBytes( "UTF-8" ));
+			cache.put( "la", local_address.getHostAddress().getBytes( "UTF-8" ));
+			cache.put( "usn", usn.getBytes( "UTF-8" ));
+			cache.put( "loc", location.toExternalForm().getBytes( "UTF-8" ));
+			
+			return( cache );
+		
+		}catch( Throwable e ){
+			
+			Debug.printStackTrace(e);
+			
+			return( null );
+		}
+	}
+	
 	public void
 	portMappingResult(
 		boolean	ok )
diff --git a/com/aelitis/net/upnp/impl/services/UPnPSSOfflineDownloaderImpl.java b/com/aelitis/net/upnp/impl/services/UPnPSSOfflineDownloaderImpl.java
new file mode 100644
index 0000000..53831f3
--- /dev/null
+++ b/com/aelitis/net/upnp/impl/services/UPnPSSOfflineDownloaderImpl.java
@@ -0,0 +1,361 @@
+/*
+ * Created on 16-Sep-2005
+ * Created by Paul Gardner
+ * Copyright (C) 2005, 2006 Aelitis, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * 
+ * AELITIS, SAS au capital de 46,603.30 euros
+ * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
+ *
+ */
+
+package com.aelitis.net.upnp.impl.services;
+
+import com.aelitis.net.upnp.UPnPAction;
+import com.aelitis.net.upnp.UPnPActionArgument;
+import com.aelitis.net.upnp.UPnPActionInvocation;
+import com.aelitis.net.upnp.UPnPException;
+import com.aelitis.net.upnp.UPnPService;
+import com.aelitis.net.upnp.services.UPnPOfflineDownloader;
+
+public class 
+UPnPSSOfflineDownloaderImpl 
+	implements UPnPOfflineDownloader
+{
+	private UPnPServiceImpl		service;
+	
+	protected
+	UPnPSSOfflineDownloaderImpl(
+		UPnPServiceImpl		_service )
+	{
+		service = _service;
+	}
+	
+	public UPnPService
+	getGenericService()
+	{
+		return( service );
+	}
+	
+	public long
+	getFreeSpace(
+		String		client_id )
+	
+		throws UPnPException
+	{
+		UPnPAction act = service.getAction( "GetFreeSpace" );
+		
+		if ( act == null ){
+						
+			throw( new UPnPException( "GetFreeSpace not supported" ));
+			
+		}else{
+					
+			UPnPActionInvocation inv = act.getInvocation();
+				
+			inv.addArgument( "NewClientID", client_id );
+			
+			UPnPActionArgument[]	args = inv.invoke();
+						
+			for (int i=0;i<args.length;i++){
+				
+				UPnPActionArgument	arg = args[i];
+			
+				String	name = arg.getName();
+				
+				if ( name.equalsIgnoreCase("NewFreeSpace")){
+					
+					return( Long.parseLong( arg.getValue()));
+					
+				}
+			}
+			
+			throw( new UPnPException( "result not found" ));
+		}
+	}
+	
+	public void
+	activate(
+		String		client_id )
+	
+		throws UPnPException
+	{
+		UPnPAction act = service.getAction( "Activate" );
+		
+		if ( act == null ){
+						
+			throw( new UPnPException( "Activate not supported" ));
+			
+		}else{
+					
+			UPnPActionInvocation inv = act.getInvocation();
+				
+			inv.addArgument( "NewClientID", client_id );
+			
+			UPnPActionArgument[]	args = inv.invoke();
+						
+			for (int i=0;i<args.length;i++){
+				
+				UPnPActionArgument	arg = args[i];
+			
+				String	name = arg.getName();
+				
+				if ( name.equalsIgnoreCase("NewStatus")){
+					
+					return;
+					
+				}
+			}
+			
+			throw( new UPnPException( "status not found" ));
+		}
+	}
+	
+	public String[] 
+	setDownloads(
+		String client_id, 
+		String hash_list )
+			
+		throws UPnPException 
+	{
+		UPnPAction act = service.getAction( "SetDownloads" );
+		
+		if ( act == null ){
+						
+			throw( new UPnPException( "SetDownloads not supported" ));
+			
+		}else{
+					
+			UPnPActionInvocation inv = act.getInvocation();
+						
+			inv.addArgument( "NewClientID", client_id );
+			inv.addArgument( "NewTorrentHashList", hash_list );
+			
+			UPnPActionArgument[]	args = inv.invoke();
+			
+			String	result	= null;
+			String	status 	= null;
+			
+			for (int i=0;i<args.length;i++){
+				
+				UPnPActionArgument	arg = args[i];
+			
+				String	name = arg.getName();
+				
+				if ( name.equalsIgnoreCase("NewSetDownloadsResultList")){
+					
+					result = arg.getValue();
+					
+				}else if ( name.equalsIgnoreCase("NewStatus")){
+					
+					status = arg.getValue();
+				}
+			}
+			
+			if ( result != null && status != null ){
+				
+				return( new String[]{ result, status });
+			}
+			
+			throw( new UPnPException( "result or status not found" ));
+		}
+	}
+	
+	public String 
+	addDownload(
+		String 	client_id, 
+		String 	hash,
+		String	torrent )
+			
+		throws UPnPException 
+	{
+		UPnPAction act = service.getAction( "AddDownload" );
+		
+		if ( act == null ){
+						
+			throw( new UPnPException( "AddDownload not supported" ));
+			
+		}else{
+					
+			UPnPActionInvocation inv = act.getInvocation();
+						
+			inv.addArgument( "NewClientID", client_id );
+			inv.addArgument( "NewTorrentHash", hash );
+			inv.addArgument( "NewTorrentData", torrent );
+			
+			UPnPActionArgument[]	args = inv.invoke();
+						
+			for (int i=0;i<args.length;i++){
+				
+				UPnPActionArgument	arg = args[i];
+			
+				String	name = arg.getName();
+				
+				if ( name.equalsIgnoreCase("NewStatus")){
+					
+					return( arg.getValue());
+				}
+			}
+			
+			throw( new UPnPException( "result not found" ));
+		}
+	}
+	
+	public String[] 
+  	updateDownload(
+  		String 	client_id, 
+  		String 	hash,
+  		String	required_map )
+  			
+  		throws UPnPException 
+  	{
+  		UPnPAction act = service.getAction( "UpdateDownload" );
+  		
+  		if ( act == null ){
+  						
+  			throw( new UPnPException( "UpdateDownload not supported" ));
+  			
+  		}else{
+  					
+  			UPnPActionInvocation inv = act.getInvocation();
+  						
+  			inv.addArgument( "NewClientID", client_id );
+ 			inv.addArgument( "NewTorrentHash", hash );
+ 			inv.addArgument( "NewPieceRequiredMap", required_map );
+  			
+  			UPnPActionArgument[]	args = inv.invoke();
+  			
+  			String	have	= null;
+  			String	status 	= null;
+  			
+  			for (int i=0;i<args.length;i++){
+  				
+  				UPnPActionArgument	arg = args[i];
+  			
+  				String	name = arg.getName();
+  				
+  				if ( name.equalsIgnoreCase("NewPieceHaveMap")){
+  					
+  					have = arg.getValue();
+  					
+  				}else if ( name.equalsIgnoreCase("NewStatus")){
+  					
+  					status = arg.getValue();
+  				}
+  			}
+  			
+  			if ( have != null && status != null ){
+  				
+  				return( new String[]{ have, status });
+  			}
+  			
+  			throw( new UPnPException( "have or status not found" ));
+  		}
+  	}
+	
+	public String
+	removeDownload(
+		String 	client_id, 
+		String 	hash )		
+	
+		throws UPnPException 
+	{
+		UPnPAction act = service.getAction( "RemoveDownload" );
+		
+		if ( act == null ){
+						
+			throw( new UPnPException( "RemoveDownload not supported" ));
+			
+		}else{
+					
+			UPnPActionInvocation inv = act.getInvocation();
+						
+			inv.addArgument( "NewClientID", client_id );
+			inv.addArgument( "NewTorrentHash", hash );
+		
+			UPnPActionArgument[]	args = inv.invoke();
+			
+			String	status 	= null;
+			
+			for (int i=0;i<args.length;i++){
+				
+				UPnPActionArgument	arg = args[i];
+			
+				String	name = arg.getName();
+				
+				if ( name.equalsIgnoreCase("NewStatus")){
+					
+					status = arg.getValue();
+				}
+			}
+			
+			if ( status != null ){
+				
+				return( status );
+			}
+			
+			throw( new UPnPException( "status not found" ));
+		}
+	}
+	
+	public String[]
+	startDownload(
+		String 	client_id, 
+		String 	hash )		
+	
+		throws UPnPException 
+	{
+		UPnPAction act = service.getAction( "StartDownload" );
+		
+		if ( act == null ){
+						
+			throw( new UPnPException( "StartDownload not supported" ));
+			
+		}else{
+					
+			UPnPActionInvocation inv = act.getInvocation();
+						
+			inv.addArgument( "NewClientID", client_id );
+			inv.addArgument( "NewTorrentHash", hash );
+		
+			UPnPActionArgument[]	args = inv.invoke();
+			
+			String	status 		= null;
+			String	data_port	= null;
+			
+			for (int i=0;i<args.length;i++){
+				
+				UPnPActionArgument	arg = args[i];
+			
+				String	name = arg.getName();
+				
+				if ( name.equalsIgnoreCase("NewStatus")){
+					
+					status = arg.getValue();
+					
+				}else if ( name.equalsIgnoreCase("NewDataPort")){
+					
+					data_port = arg.getValue();
+				}
+			}
+			
+			if ( status != null && data_port != null ){
+				
+				return( new String[]{ data_port, status });
+			}
+			
+			throw( new UPnPException( "status or data port not found" ));
+		}
+	}
+}
diff --git a/com/aelitis/net/upnp/impl/services/UPnPServiceImpl.java b/com/aelitis/net/upnp/impl/services/UPnPServiceImpl.java
index a26eff8..d12f943 100644
--- a/com/aelitis/net/upnp/impl/services/UPnPServiceImpl.java
+++ b/com/aelitis/net/upnp/impl/services/UPnPServiceImpl.java
@@ -262,6 +262,10 @@ UPnPServiceImpl
 			
 			return( new UPnPSSWANCommonInterfaceConfigImpl( this ));
 			
+		}else if ( service_type.equalsIgnoreCase("urn:schemas-upnp-org:service:VuzeOfflineDownloaderService:1")){
+			
+			return( new UPnPSSOfflineDownloaderImpl( this ));
+			
 		}else{
 			
 			return( null );
diff --git a/com/aelitis/net/upnp/impl/ssdp/SSDPCore.java b/com/aelitis/net/upnp/impl/ssdp/SSDPCore.java
index ceff109..8dc0041 100644
--- a/com/aelitis/net/upnp/impl/ssdp/SSDPCore.java
+++ b/com/aelitis/net/upnp/impl/ssdp/SSDPCore.java
@@ -69,7 +69,7 @@ SSDPCore
 		try{
 			class_mon.enter();
 		
-			String	key = group_address + ":" + group_port;// + ":" + control_port;
+			String	key = group_address + ":" + group_port + ":" + control_port;
 			
 			SSDPCore	singleton = (SSDPCore)singletons.get( key );
 			
@@ -106,7 +106,7 @@ SSDPCore
 
 	private Set<String>		ignore_mx	= new HashSet();
 	
-	public
+	private
 	SSDPCore(
 		UPnPSSDPAdapter		_adapter,
 		String				_group_address,
diff --git a/com/aelitis/net/upnp/impl/ssdp/SSDPIGDImpl.java b/com/aelitis/net/upnp/impl/ssdp/SSDPIGDImpl.java
index 955fb62..a5f14e9 100644
--- a/com/aelitis/net/upnp/impl/ssdp/SSDPIGDImpl.java
+++ b/com/aelitis/net/upnp/impl/ssdp/SSDPIGDImpl.java
@@ -64,7 +64,7 @@ SSDPIGDImpl
 				upnp.getAdapter(),
 				UPnPSSDP.SSDP_GROUP_ADDRESS,
 				UPnPSSDP.SSDP_GROUP_PORT,
-				UPnPSSDP.SSDP_CONTROL_PORT,
+				0,
 				_selected_interfaces );
 		
 		ssdp_core.addListener( this );
diff --git a/com/aelitis/net/upnp/services/UPnPOfflineDownloader.java b/com/aelitis/net/upnp/services/UPnPOfflineDownloader.java
new file mode 100644
index 0000000..f657c76
--- /dev/null
+++ b/com/aelitis/net/upnp/services/UPnPOfflineDownloader.java
@@ -0,0 +1,84 @@
+/*
+ * Created on 15-Jun-2004
+ * Created by Paul Gardner
+ * Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * 
+ * AELITIS, SAS au capital de 46,603.30 euros
+ * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
+ *
+ */
+
+package com.aelitis.net.upnp.services;
+
+import com.aelitis.net.upnp.UPnPException;
+
+/**
+ * @author parg
+ *
+ */
+
+public interface 
+UPnPOfflineDownloader
+	extends UPnPSpecificService
+{
+	public long
+	getFreeSpace(
+		String		client_id )
+	
+		throws UPnPException;
+	
+	public void
+	activate(
+		String		client_id )
+	
+		throws UPnPException;
+	
+	public String
+	addDownload(
+		String		client_id,
+		String		hash_list,
+		String		torrent )
+	
+		throws UPnPException;
+	
+	public String[]
+	updateDownload(
+		String		client_id,
+		String		hash_list,
+		String		required_map )
+	
+		throws UPnPException;
+	
+	public String[]
+	setDownloads(
+		String		client_id,
+		String		hash_list )
+	
+		throws UPnPException;
+
+	public String
+	removeDownload(
+		String		client_id,
+		String		hash )
+	
+		throws UPnPException;
+	
+	public String[]
+	startDownload(
+		String		client_id,
+		String		hash )
+	
+		throws UPnPException;
+}
diff --git a/debian/README.source b/debian/README.source
deleted file mode 100644
index 14badfb..0000000
--- a/debian/README.source
+++ /dev/null
@@ -1,15 +0,0 @@
-azureus for Debian
-------------------
-
-The azureus source package uses quilt to apply and remove its patches. Please
-refer to /usr/share/doc/quilt/README.source for information about how to use
-quilt for source packages.
-
-The quilt series is generated from the Git repository, using TopGit.
-This process is documented in /usr/share/doc/topgit/HOWTO-tg2quilt.gz .
-
-The azureus package uses the branch layout described in the aforementioned
-document.
-
--- Adrian Perez <adrianperez.deb at gmail.com> Mon, 31 Aug 2009 18:20:35 -0400
-
diff --git a/debian/azureus.desktop b/debian/azureus.desktop
index ab04f71..4f1058a 100644
--- a/debian/azureus.desktop
+++ b/debian/azureus.desktop
@@ -1,6 +1,6 @@
 [Desktop Entry]
 Categories=Java;Network;FileTransfer;P2P
-Comment=peer-to-peer file distribution tool
+Comment=Download and share files using the BitTorrent P2P network
 Exec=azureus %f
 GenericName=BitTorrent client
 Icon=Azureus
diff --git a/debian/changelog b/debian/changelog
index 9b35933..744b2c2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,18 @@
+azureus (4.3.0.0-1~2.gbpa9c97b) UNRELEASED; urgency=low
+
+  ** SNAPSHOT build @a9c97bb85eaf7d3e701b91eb0a7922f1efb08f9b **
+
+  * New upstream release. Closes: LP#488507.
+  * Use "3.0 (quilt)" source package format.
+  * debian/control: Allow uploads for Debian Maintainers.
+  * debian/azureus.1: Get rid of duplicate "azureus" around Synopsis.
+  * debian/patches: 
+    - Remove fixes/multi-announce-deadlock.diff (upstream).
+    - Remove fixes/utf8-encoding.diff (upstream).
+  * debian/azureus.desktop: Improve Comment for Desktop Entry.
+
+ -- Adrian Perez <adrianperez.deb at gmail.com>  Wed, 02 Dec 2009 09:13:53 -0500
+
 azureus (4.2.0.8-3) unstable; urgency=low
 
   * debian/patches:
diff --git a/debian/control b/debian/control
index 3d75860..24e52f3 100644
--- a/debian/control
+++ b/debian/control
@@ -3,7 +3,8 @@ Section: net
 Priority: optional
 Maintainer: Debian Java Maintainers <pkg-java-maintainers at lists.alioth.debian.org>
 Uploaders: Adrian Perez <adrianperez.deb at gmail.com>
-Build-Depends: ant, cdbs, quilt, debhelper (>= 7.0)
+DM-Upload-Allowed: yes
+Build-Depends: ant, cdbs, debhelper (>= 7.0)
 Build-Depends-Indep: openjdk-6-jdk, libcommons-cli-java, liblog4j1.2-java, 
  libswt-gtk-3.4-java, junit
 Standards-Version: 3.8.3
diff --git a/debian/docs b/debian/docs
index cdb8475..b3000fe 100644
--- a/debian/docs
+++ b/debian/docs
@@ -1,2 +1 @@
 debian/README.multiuser
-debian/README.source
diff --git a/debian/patches/debian/speedtest.diff b/debian/patches/debian/speedtest.diff
index 0f3a8b6..0c61cfc 100644
--- a/debian/patches/debian/speedtest.diff
+++ b/debian/patches/debian/speedtest.diff
@@ -40,4 +40,4 @@ index 01022eb..76e27df 100644
              retVal = sendRequest( request );
  
 -- 
-tg: (320870a..) debian/speedtest (depends on: upstream)
+tg: (7f589b9..) debian/speedtest (depends on: upstream)
diff --git a/debian/patches/debian/update-disable.diff b/debian/patches/debian/update-disable.diff
index 395cab5..cd058e0 100644
--- a/debian/patches/debian/update-disable.diff
+++ b/debian/patches/debian/update-disable.diff
@@ -14,10 +14,10 @@ Signed-off-by: Adrian Perez <adrianperez.deb at gmail.com>
  4 files changed, 21 insertions(+), 6 deletions(-)
 
 diff --git a/com/aelitis/azureus/ui/swt/Initializer.java b/com/aelitis/azureus/ui/swt/Initializer.java
-index 54f4367..5571a3a 100644
+index 8a959c4..9069f3d 100644
 --- a/com/aelitis/azureus/ui/swt/Initializer.java
 +++ b/com/aelitis/azureus/ui/swt/Initializer.java
-@@ -40,9 +40,10 @@ import org.gudy.azureus2.ui.swt.networks.SWTNetworkSelection;
+@@ -44,9 +44,10 @@ import org.gudy.azureus2.ui.swt.networks.SWTNetworkSelection;
  import org.gudy.azureus2.ui.swt.pluginsinstaller.InstallPluginWizard;
  import org.gudy.azureus2.ui.swt.progress.ProgressWindow;
  import org.gudy.azureus2.ui.swt.update.UpdateMonitor;
@@ -29,7 +29,7 @@ index 54f4367..5571a3a 100644
  import com.aelitis.azureus.core.*;
  import com.aelitis.azureus.core.cnetwork.ContentNetwork;
  import com.aelitis.azureus.core.messenger.ClientMessageContext;
-@@ -294,12 +295,15 @@ public class Initializer
+@@ -358,12 +359,15 @@ public class Initializer
  					}
  					
  					reportCurrentTaskByKey("splash.openViews");
@@ -47,7 +47,7 @@ index 54f4367..5571a3a 100644
  	
  					//Tell listeners that all is initialized :
 diff --git a/org/gudy/azureus2/ui/swt/mainwindow/Initializer.java b/org/gudy/azureus2/ui/swt/mainwindow/Initializer.java
-index 3991ffa..e19cfee 100644
+index 620829f..d9e4478 100644
 --- a/org/gudy/azureus2/ui/swt/mainwindow/Initializer.java
 +++ b/org/gudy/azureus2/ui/swt/mainwindow/Initializer.java
 @@ -45,9 +45,10 @@ import org.gudy.azureus2.ui.swt.networks.SWTNetworkSelection;
@@ -96,7 +96,7 @@ index 82fd9ae..b87f55a 100644
  	}
  	
 diff --git a/org/gudy/azureus2/update/CoreUpdateChecker.java b/org/gudy/azureus2/update/CoreUpdateChecker.java
-index c1ade9d..7907dc9 100644
+index a19e928..75dd887 100644
 --- a/org/gudy/azureus2/update/CoreUpdateChecker.java
 +++ b/org/gudy/azureus2/update/CoreUpdateChecker.java
 @@ -127,8 +127,11 @@ CoreUpdateChecker
@@ -113,4 +113,4 @@ index c1ade9d..7907dc9 100644
  	
  	public String
 -- 
-tg: (25674b0..) debian/update-disable (depends on: upstream)
+tg: (3001c78..) debian/update-disable (depends on: upstream)
diff --git a/debian/patches/fixes/encoding.diff b/debian/patches/fixes/encoding.diff
index 7abf2ae..4f5ab55 100644
--- a/debian/patches/fixes/encoding.diff
+++ b/debian/patches/fixes/encoding.diff
@@ -12,7 +12,7 @@ Signed-off-by: Adrian Perez <adrianperez.deb at gmail.com>
  1 files changed, 4 insertions(+), 4 deletions(-)
 
 diff --git a/com/aelitis/azureus/core/metasearch/impl/DateParserRegex.java b/com/aelitis/azureus/core/metasearch/impl/DateParserRegex.java
-index b2e8560..b9099d0 100644
+index 5a7d5ee..89ca61d 100644
 --- a/com/aelitis/azureus/core/metasearch/impl/DateParserRegex.java
 +++ b/com/aelitis/azureus/core/metasearch/impl/DateParserRegex.java
 @@ -50,17 +50,17 @@ public class DateParserRegex extends DateParser {
@@ -38,4 +38,4 @@ index b2e8560..b9099d0 100644
  	public DateParserRegex() {
  		this("GMT-7",true,null);
 -- 
-tg: (c80152d..) fixes/encoding (depends on: fixes/platform)
+tg: (4f168c3..) fixes/encoding (depends on: fixes/platform)
diff --git a/debian/patches/fixes/multi-announce-deadlock.diff b/debian/patches/fixes/multi-announce-deadlock.diff
deleted file mode 100644
index 955cf99..0000000
--- a/debian/patches/fixes/multi-announce-deadlock.diff
+++ /dev/null
@@ -1,60 +0,0 @@
-From: Adrian Perez <adrianperez.deb at gmail.com>
-Subject: [PATCH] fixes/multi-announce-deadlock
-
-Fix freeze when torrents containing .onion tracker announce URLs
-are added, comprising the Azureus multi-announce implementation.
-
-Thanks: Arron Mogge (TuxPaper)
-Bug: http://bugs.debian.org/551363
-Signed-off-by: Adrian Perez <adrianperez.deb at gmail.com>
-
----
- .../ui/swt/networks/SWTNetworkSelection.java       |   12 +++++++++---
- 1 files changed, 9 insertions(+), 3 deletions(-)
-
-diff --git a/org/gudy/azureus2/ui/swt/networks/SWTNetworkSelection.java b/org/gudy/azureus2/ui/swt/networks/SWTNetworkSelection.java
-index 261c38a..fed839a 100644
---- a/org/gudy/azureus2/ui/swt/networks/SWTNetworkSelection.java
-+++ b/org/gudy/azureus2/ui/swt/networks/SWTNetworkSelection.java
-@@ -77,7 +77,7 @@ SWTNetworkSelection
- 		final classifierDialog[]	dialog = new classifierDialog[1];
- 		
- 		try{
--			display.asyncExec(
-+			Utils.execSWTThread(
- 				new AERunnable()
- 				{
- 					public void
-@@ -120,7 +120,7 @@ SWTNetworkSelection
- 			
- 			if ( display.isDisposed()){
- 				
--				sem.release();
-+				sem.releaseForever();
- 				
- 				return;
- 			}
-@@ -249,6 +249,12 @@ SWTNetworkSelection
- 			Utils.centreWindow( shell );
- 
- 			shell.open ();   
-+			
-+			while (!shell.isDisposed()) {
-+				if (display != null && !display.isDisposed() && !display.readAndDispatch()) {
-+					display.sleep();
-+				}
-+			}
- 		}
-    
- 		protected void
-@@ -277,7 +283,7 @@ SWTNetworkSelection
- 	 		}
- 	 		
- 	 		shell.dispose();
--	 		sem.release();
-+	 		sem.releaseForever();
- 	 	}
- 	 	
- 	 	protected String[]
--- 
-tg: (320870a..) fixes/multi-announce-deadlock (depends on: upstream)
diff --git a/debian/patches/fixes/multiuser.diff b/debian/patches/fixes/multiuser.diff
index ac9d911..45f86ec 100644
--- a/debian/patches/fixes/multiuser.diff
+++ b/debian/patches/fixes/multiuser.diff
@@ -1,10 +1,10 @@
 From: Stefano Maioli <smaioli at gmx.com>
 Subject: [PATCH] fixes/multiuser
 
-Allow one single running instance of Azureus per user, instead of one per 
+Allow one single instance of Azureus per user, instead of one per
 machine. Add authentication to the control interface.
 
-Bug-Debian: http://bugs.debian.org/329018 
+Bug-Debian: http://bugs.debian.org/329018
 Bug-Ubuntu: https://bugs.launchpad.net/222630
 Acked-by: Onkar Shinde <onkarshinde at ubuntu.com>
 Signed-off-by: Adrian Perez <adrianperez.deb at gmail.com>
@@ -430,17 +430,16 @@ index 023a557..7619e99 100644
                }
              }
 diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java
-index 5fa1571..34ff660 100644
+index 00171c7..b321361 100644
 --- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java
 +++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java
-@@ -102,15 +102,15 @@ public class ConfigSectionConnection implements UISWTConfigSection {
+@@ -102,14 +102,14 @@ public class ConfigSectionConnection implements UISWTConfigSection {
  		label.setLayoutData(gridData);
  
  		final IntParameter tcplisten = new IntParameter(cMiniArea,
 -				"TCP.Listen.Port", 1, 65535);
 +				"TCP.Listen.Port", 1, 49151);
  		gridData = new GridData();
- 		gridData.widthHint = 40;
  		tcplisten.setLayoutData(gridData);
  
  		tcplisten.addChangeListener(new ParameterChangeAdapter() {
@@ -452,16 +451,16 @@ index 5fa1571..34ff660 100644
  					tcplisten.setValue(toValue);
  				}
  
-@@ -130,7 +130,7 @@ public class ConfigSectionConnection implements UISWTConfigSection {
+@@ -129,7 +129,7 @@ public class ConfigSectionConnection implements UISWTConfigSection {
  			label.setLayoutData(gridData);
  
  			final IntParameter udp_listen = new IntParameter(cMiniArea,
 -					"UDP.Listen.Port", 1, 65535);
 +					"UDP.Listen.Port", 1, 49151);
  			gridData = new GridData();
- 			gridData.widthHint = 40;
  			udp_listen.setLayoutData(gridData);
-@@ -139,8 +139,8 @@ public class ConfigSectionConnection implements UISWTConfigSection {
+ 
+@@ -137,8 +137,8 @@ public class ConfigSectionConnection implements UISWTConfigSection {
  			
  			udp_listen.addChangeListener(new ParameterChangeAdapter() {
  				public void intParameterChanging(Parameter p, int toValue) {
@@ -472,7 +471,7 @@ index 5fa1571..34ff660 100644
  						udp_listen.setValue(toValue);
  					}
  
-@@ -175,8 +175,8 @@ public class ConfigSectionConnection implements UISWTConfigSection {
+@@ -173,8 +173,8 @@ public class ConfigSectionConnection implements UISWTConfigSection {
  					new ParameterChangeAdapter() 
  					{
  						public void intParameterChanging(Parameter p, int toValue) {
@@ -483,7 +482,7 @@ index 5fa1571..34ff660 100644
  								non_data_udp_listen.setValue(toValue);
  							}
  						}
-@@ -191,7 +191,7 @@ public class ConfigSectionConnection implements UISWTConfigSection {
+@@ -189,7 +189,7 @@ public class ConfigSectionConnection implements UISWTConfigSection {
  									
  									int udp_listen_port = udp_listen.getValue();
  			
@@ -493,20 +492,20 @@ index 5fa1571..34ff660 100644
  										COConfigurationManager.setParameter( "UDP.NonData.Listen.Port", udp_listen_port );
  										
 diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java
-index 487cb27..590d1d1 100644
+index 0b1ad25..bb5ce14 100644
 --- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java
 +++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java
-@@ -173,7 +173,7 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
+@@ -168,7 +168,7 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
  		Label lpbind = new Label(gSocket, SWT.NULL);
  		Messages.setLanguageText(lpbind, CFG_PREFIX + "bind_port");
  		final IntParameter port_bind = new IntParameter(gSocket,
 -				"network.bind.local.port", 0, 65535);
 +				"network.bind.local.port", 0, 49151);
  		gridData = new GridData();
- 		gridData.widthHint = 40;
  		port_bind.setLayoutData(gridData);
+ 		
 diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java
-index 5f77ef7..a7531b2 100644
+index fce3910..fabed84 100644
 --- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java
 +++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java
 @@ -176,7 +176,7 @@ ConfigSectionTrackerClient
@@ -519,4 +518,4 @@ index 5f77ef7..a7531b2 100644
  			} catch (NumberFormatException e) {}
  			p.setValue("");
 -- 
-tg: (cb188fa..) fixes/multiuser (depends on: fixes/sunsecurity)
+tg: (49ad0c1..) fixes/multiuser (depends on: fixes/sunsecurity)
diff --git a/debian/patches/fixes/platform.diff b/debian/patches/fixes/platform.diff
index 0626132..32fafbd 100644
--- a/debian/patches/fixes/platform.diff
+++ b/debian/patches/fixes/platform.diff
@@ -8,10 +8,10 @@ Signed-off-by: Adrian Perez <adrianperez.deb at gmail.com>
 
 ---
  .../core/update/impl/AzureusRestarterImpl.java     |    6 +++++-
- .../ui/swt/views/skin/TorrentListViewsUtils.java   |    6 ++++--
+ .../ui/swt/views/skin/TorrentListViewsUtils.java   |    8 +++++++-
  .../azureus2/platform/PlatformManagerFactory.java  |    4 ++--
  .../platform/PlatformManagerPluginDelegate.java    |   15 ++++++++++++---
- 4 files changed, 23 insertions(+), 8 deletions(-)
+ 4 files changed, 26 insertions(+), 7 deletions(-)
 
 diff --git a/com/aelitis/azureus/core/update/impl/AzureusRestarterImpl.java b/com/aelitis/azureus/core/update/impl/AzureusRestarterImpl.java
 index b4438fb..d238dc6 100644
@@ -47,30 +47,32 @@ index b4438fb..d238dc6 100644
  			/*
  			 * Some results:
 diff --git a/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java b/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java
-index 1fdc4df..6ccac5c 100644
+index 190af45..cb104fe 100644
 --- a/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java
 +++ b/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java
-@@ -78,8 +78,9 @@ import com.aelitis.azureus.util.DLReferals;
+@@ -76,8 +76,10 @@ import com.aelitis.azureus.util.ContentNetworkUtils;
+ import com.aelitis.azureus.util.DLReferals;
  import com.aelitis.azureus.util.DataSourceUtils;
  import com.aelitis.azureus.util.PlayUtils;
- import com.aelitis.azureus.util.PublishUtils;
+-import com.aelitis.azureus.util.win32.Win32Utils;
+ 
 +/* --- Adrian Perez: Don't import this when building for Linux.
- import com.aelitis.azureus.util.win32.Win32Utils;
--
++import com.aelitis.azureus.util.win32.Win32Utils;
 +*/
  /**
   * @author TuxPaper
   * @created Oct 12, 2006
-@@ -640,7 +641,7 @@ public class TorrentListViewsUtils
+@@ -615,6 +617,9 @@ public class TorrentListViewsUtils
+ 	 */
  	private static boolean runInMediaPlayer(String mediaFile) {
  
- 		debugDCAD("enter - runInMediaPlayer");
--
++	// debugDCAD("enter - runInMediaPlayer");
++
 +/* --- Adrian Perez: Don't use Win32 media player. Always return false.
  		if (Constants.isWindows) {
  			String wmpEXE = Win32Utils.getWMP();
  			if (new File(wmpEXE).exists()) {
-@@ -652,6 +653,7 @@ public class TorrentListViewsUtils
+@@ -626,6 +631,7 @@ public class TorrentListViewsUtils
  				}
  			}
  		}
@@ -137,4 +139,4 @@ index 3beeb39..b98a0bf 100644
  			pluginProperties.setProperty("plugin.name", "Platform-Specific Support");
  			pluginProperties.setProperty("plugin.version", "1.0");
 -- 
-tg: (320870a..) fixes/platform (depends on: upstream)
+tg: (7f589b9..) fixes/platform (depends on: upstream)
diff --git a/debian/patches/fixes/sunsecurity.diff b/debian/patches/fixes/sunsecurity.diff
index 007f184..92c8666 100644
--- a/debian/patches/fixes/sunsecurity.diff
+++ b/debian/patches/fixes/sunsecurity.diff
@@ -9,61 +9,33 @@ future. Also, this causes a FTBFS when using OpenJDK.
 Signed-off-by: Adrian Perez <adrianperez.deb at gmail.com>
 
 ---
- org/gudy/azureus2/core3/internat/MessageText.java |   18 ++++++++----------
- 1 files changed, 8 insertions(+), 10 deletions(-)
+ org/gudy/azureus2/core3/internat/MessageText.java |    7 ++++++-
+ 1 files changed, 6 insertions(+), 1 deletions(-)
 
 diff --git a/org/gudy/azureus2/core3/internat/MessageText.java b/org/gudy/azureus2/core3/internat/MessageText.java
-index 816f30c..6f397bb 100644
+index 8358049..fed112e 100644
 --- a/org/gudy/azureus2/core3/internat/MessageText.java
 +++ b/org/gudy/azureus2/core3/internat/MessageText.java
-@@ -24,7 +24,9 @@ import java.io.FilenameFilter;
+@@ -24,6 +24,9 @@ import java.io.FilenameFilter;
  import java.net.URI;
  import java.net.URL;
  import java.net.URLClassLoader;
 +/* --- Adrian Perez: Don't use AccessController.
- import java.security.AccessController;
++import java.security.AccessController;
 +*/
  import java.util.*;
  import java.util.jar.JarEntry;
  import java.util.jar.JarFile;
-@@ -38,9 +40,9 @@ import org.gudy.azureus2.core3.util.Constants;
+@@ -37,7 +40,9 @@ import org.gudy.azureus2.core3.util.Constants;
  import org.gudy.azureus2.core3.util.Debug;
  import org.gudy.azureus2.core3.util.FileUtil;
  import org.gudy.azureus2.core3.util.SystemProperties;
 -
 +/* --- Adrian Perez: Don't use sun.security.
- import sun.security.action.GetPropertyAction;
--
++import sun.security.action.GetPropertyAction;
 +*/
+ 
  /**
   * @author Arbeiten
-  * 
-@@ -768,11 +770,9 @@ public class MessageText {
-   	// at startup to determine the locale.  Too bad they didn't provide
-   	// a way to call this code explicitly..
-     String language, region, country, variant;
--    language = (String) AccessController.doPrivileged(
--                    new GetPropertyAction("user.language", "en"));
-+    language = System.getProperty("user.language", "en");
-     // for compatibility, check for old user.region property
--    region = (String) AccessController.doPrivileged(
--                    new GetPropertyAction("user.region"));
-+    region = System.getProperty("user.region");
-     if (region != null) {
-         // region can be of form country, country_variant, or _variant
-         int i = region.indexOf('_');
-@@ -784,10 +784,8 @@ public class MessageText {
-             variant = "";
-         }
-     } else {
--        country = (String) AccessController.doPrivileged(
--                        new GetPropertyAction("user.country", ""));
--        variant = (String) AccessController.doPrivileged(
--                        new GetPropertyAction("user.variant", ""));
-+        country = System.getProperty("user.country", "");
-+        variant = System.getProperty("user.variant", "");
-     }
-     changeLocale(new Locale(language, country, variant));
-     COConfigurationManager.removeParameter("locale");
 -- 
-tg: (9455772..) fixes/sunsecurity (depends on: fixes/encoding)
+tg: (61d59af..) fixes/sunsecurity (depends on: fixes/encoding)
diff --git a/debian/patches/fixes/utf8-encoding.diff b/debian/patches/fixes/utf8-encoding.diff
deleted file mode 100644
index 159ccca..0000000
--- a/debian/patches/fixes/utf8-encoding.diff
+++ /dev/null
@@ -1,391 +0,0 @@
-From: Arron Moge <tuxpaper at users.sourceforge.net>
-Subject: [PATCH] fixes/utf8-encoding
-
-Fixes filename encoding issues when torrents contain
-UTF-8 chars.
-
-Origin: https://jira.vuze.com/secure/attachment/12798/utf8torrents.patch
-Bug: http://jira.vuze.com/browse/SUP-18
-Bug-Debian: http://bugs.debian.org/502879
-
-Signed-off-by: Adrian Perez <adrianperez.deb at gmail.com>
-
----
- org/gudy/azureus2/core3/torrent/TOTorrent.java     |    2 +
- .../torrent/impl/TOTorrentDeserialiseImpl.java     |   49 ++++++++-
- .../core3/torrent/impl/TOTorrentFileImpl.java      |  118 +++++++++++++++++++-
- .../azureus2/core3/torrent/impl/TOTorrentImpl.java |   47 ++------
- 4 files changed, 170 insertions(+), 46 deletions(-)
-
-diff --git a/org/gudy/azureus2/core3/torrent/TOTorrent.java b/org/gudy/azureus2/core3/torrent/TOTorrent.java
-index df5c21d..d9760e2 100644
---- a/org/gudy/azureus2/core3/torrent/TOTorrent.java
-+++ b/org/gudy/azureus2/core3/torrent/TOTorrent.java
-@@ -44,6 +44,8 @@ TOTorrent
- 		 */
- 	
- 	public static final String	AZUREUS_PRIVATE_PROPERTIES		= "azureus_private_properties";
-+
-+	public static final String ENCODING_ACTUALLY_UTF8_KEYS = "utf8 keys";
- 	
- 	/**
- 	 * Get the name of the torrent
-diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java
-index 510d2ce..259043d 100644
---- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java
-+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java
-@@ -466,7 +466,9 @@ TOTorrentDeserialiseImpl
- 				throw( new TOTorrentException( "Decode fails, 'info' element not found'",
- 												TOTorrentException.RT_DECODE_FAILS ));
- 			}
--		
-+	
-+			boolean hasUTF8Keys = info.containsKey(TK_NAME_UTF8);
-+	
- 			setName((byte[])info.get( TK_NAME ));
- 				
- 			long	piece_length = ((Long)info.get( TK_PIECE_LENGTH )).longValue();
-@@ -484,12 +486,20 @@ TOTorrentDeserialiseImpl
- 			Long simple_file_length = (Long)info.get( TK_LENGTH );
- 			
- 			long	total_length = 0;
-+
-+			String encoding = getAdditionalStringProperty("encoding");
-+			hasUTF8Keys &= encoding == null || encoding.equals(ENCODING_ACTUALLY_UTF8_KEYS);
- 			
- 			if ( simple_file_length != null ){
- 			
- 				setSimpleTorrent( true );
- 				
- 				total_length = simple_file_length.longValue();
-+
-+				if (hasUTF8Keys) {
-+					setNameUTF8((byte[])info.get( TK_NAME_UTF8 ));
-+					setAdditionalStringProperty("encoding", ENCODING_ACTUALLY_UTF8_KEYS);
-+				}
- 				
- 				setFiles( new TOTorrentFileImpl[]{ new TOTorrentFileImpl( this, 0, total_length, new byte[][]{getName()})});
- 				
-@@ -500,7 +510,23 @@ TOTorrentDeserialiseImpl
- 				List	meta_files = (List)info.get( TK_FILES );
- 			
- 				TOTorrentFileImpl[] files = new TOTorrentFileImpl[ meta_files.size()];
--			
-+
-+				if (hasUTF8Keys) {
-+				for (int i=0;i<files.length;i++){
-+	                        	Map file_map = (Map)meta_files.get(i);
-+                                
-+	                               	hasUTF8Keys &= file_map.containsKey(TK_PATH_UTF8);
-+	                        	if (!hasUTF8Keys) {
-+	                                	break;
-+	                        	}
-+	                        }
-+
-+				if (hasUTF8Keys) {
-+					setNameUTF8((byte[])info.get( TK_NAME_UTF8 ));
-+					setAdditionalStringProperty("encoding", ENCODING_ACTUALLY_UTF8_KEYS);
-+				}	
-+				}
-+
- 				for (int i=0;i<files.length;i++){
- 					
- 					Map	file_map = (Map)meta_files.get(i);
-@@ -508,6 +534,8 @@ TOTorrentDeserialiseImpl
- 					long	len = ((Long)file_map.get( TK_LENGTH )).longValue();
- 					
- 					List	paths = (List)file_map.get( TK_PATH );
-+
-+					List	paths8 = (List)file_map.get( TK_PATH_UTF8 );
- 						
- 					byte[][]	path_comps = new byte[paths.size()][];
- 					
-@@ -516,8 +544,20 @@ TOTorrentDeserialiseImpl
- 						path_comps[j] = (byte[])paths.get(j);
- 					}
- 					
--					TOTorrentFileImpl file = files[i] = new TOTorrentFileImpl( this, total_length, len, path_comps );
-+					TOTorrentFileImpl file;
- 					
-+					if (hasUTF8Keys) {
-+					byte[][]	path_comps8 = new byte[paths8.size()][];
-+
-+					for (int j=0;j<paths8.size();j++) {
-+						
-+						path_comps8[j] = (byte[])paths8.get(j);
-+					}
-+
-+						file = files[i] = new TOTorrentFileImpl( this, total_length, len, path_comps, path_comps8 );
-+					} else {
-+						file = files[i] = new TOTorrentFileImpl( this, total_length, len, path_comps );
-+					}
- 					total_length += len;
- 					
- 						// preserve any non-standard attributes
-@@ -532,6 +572,7 @@ TOTorrentDeserialiseImpl
- 								key.equals( TK_PATH )){
- 									
- 							// standard
-+							// we don't skip TK_PATH_UTF8 because some code might assume getAdditionalProperty can get it
- 						}else{
- 							
- 							file.setAdditionalProperty( key, file_map.get( key ));
-@@ -742,4 +783,4 @@ TOTorrentDeserialiseImpl
- 			System.out.println( indent + name + "{byte[], length " + value.length + "}" );
- 		}
- 	}
--}
-\ No newline at end of file
-+}
-diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java
-index 85d9359..a29fb4d 100644
---- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java
-+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java
-@@ -36,6 +36,7 @@ TOTorrentFileImpl
- 	private final TOTorrent	torrent;
- 	private final long		file_length;
- 	private final byte[][]	path_components;
-+	private final byte[][]	path_components_utf8;
- 	
- 	private final int		first_piece_number;
- 	private final int		last_piece_number;
-@@ -87,6 +88,10 @@ TOTorrentFileImpl
- 			path_components		= new byte[temp.size()][];
- 			
- 			temp.copyInto( path_components );
-+
-+			path_components_utf8 		= new byte[temp.size()][];
-+
-+			temp.copyInto( path_components_utf8 );
- 			
- 			checkComponents();
- 			
-@@ -109,6 +114,31 @@ TOTorrentFileImpl
- 		torrent				= _torrent;
- 		file_length			= _len;
- 		path_components		= _path_components;
-+		path_components_utf8 = null;
-+
-+		first_piece_number 	= (int)( _torrent_offset / torrent.getPieceLength());
-+		last_piece_number       = (int)(( _torrent_offset + file_length - 1 ) /  torrent.getPieceLength());
-+
-+		is_utf8                         = false;
-+
-+		checkComponents();
-+	}
-+
-+	protected
-+	TOTorrentFileImpl(
-+		TOTorrent	_torrent,
-+		long		_torrent_offset,
-+		long		_len,
-+		byte[][]	_path_components,
-+		byte[][]	_path_components_utf8 )
-+
-+		throws TOTorrentException
-+	{
-+		torrent                         = _torrent;
-+		file_length                     = _len;
-+		path_components         = _path_components;
-+		path_components_utf8 = _path_components_utf8;
-+
- 		
- 		first_piece_number 	= (int)( _torrent_offset / torrent.getPieceLength());
- 		last_piece_number	= (int)(( _torrent_offset + file_length - 1 ) /  torrent.getPieceLength());
-@@ -148,10 +178,24 @@ TOTorrentFileImpl
- 	}
- 	
- 	public byte[][]
--	getPathComponents()
-+	getPathComponentsBasic()
- 	{
- 		return( path_components );
- 	}
-+
-+	public byte[][]
-+	getPathComponents()
-+	{
-+		return path_components_utf8 == null ? path_components : path_components_utf8;
-+	}
-+
-+	public byte[][]
-+	getPathComponentsUTF8()
-+	{
-+		return( path_components_utf8 );
-+	}
-+
-+
- 	
- 	protected boolean
- 	isUTF8()
-@@ -208,22 +252,23 @@ TOTorrentFileImpl
- 		}
- 
- 		if (decoder != null) {
--			for (int j = 0; j < path_components.length; j++) {
-+			byte[][] components = getPathComponents();
-+			for (int j = 0; j < components.length; j++) {
- 
- 				try {
- 					String comp;
- 					try {
--						comp = decoder.decodeString(path_components[j]);
-+						comp = decoder.decodeString(components[j]);
- 					} catch (UnsupportedEncodingException e) {
- 						System.out.println("file - unsupported encoding!!!!");
- 						try {
--							comp = new String(path_components[j]);
-+							comp = new String(components[j]);
- 						} catch (Exception e2) {
- 							comp = "UnsupportedEncoding";
- 						}
- 					}
- 	
--					comp = FileUtil.convertOSSpecificChars(comp, j != path_components.length-1 );
-+					comp = FileUtil.convertOSSpecificChars(comp, j != components.length-1 );
- 	
- 					sRelativePath += (j == 0 ? "" : File.separator) + comp;
- 				} catch (Exception ex) {
-@@ -235,4 +280,67 @@ TOTorrentFileImpl
- 		}
- 		return sRelativePath;
- 	}
-+
-+	/**
-+	 * @return
-+	 * 
-+	 * @since 4.1.0.5
-+	 */
-+	public Map serializeToMap() {
-+		Map	file_map = new HashMap();
-+		
-+		file_map.put( TOTorrentImpl.TK_LENGTH, new Long( getLength()));
-+
-+		List path = new ArrayList();
-+		
-+		file_map.put ( TOTorrentImpl.TK_PATH, path );
-+		
-+		byte[][] 	path_comps = getPathComponentsBasic();
-+
-+		for (int j=0;j<path_comps.length;j++) {
-+			
-+			path.add( path_comps[j] );
-+		}
-+
-+		if ( isUTF8()) {
-+			List utf8_path = new ArrayList();
-+			
-+			file_map.put( TOTorrentImpl.TK_PATH_UTF8, utf8_path );
-+			
-+			for (int j=0;j<path_comps.length;j++){
-+				
-+				utf8_path.add( path_comps[j]);
-+			}
-+		} else {
-+			
-+			byte[][]        utf8_path_comps = getPathComponentsUTF8();
-+			
-+			if (utf8_path_comps != null) {
-+			List utf8_path = new ArrayList();
-+
-+			file_map.put( TOTorrentImpl.TK_PATH_UTF8, utf8_path );
-+
-+			for (int j=0;j<utf8_path_comps.length;j++){ 
-+				
-+				utf8_path.add( utf8_path_comps[j]);
-+			}
-+			}
-+		}
-+
-+		Map file_additional_properties = getAdditionalProperties();
-+
-+		Iterator prop_it = file_additional_properties.keySet().iterator();
-+
-+		while( prop_it.hasNext()){
-+
-+			String  key = (String)prop_it.next();
-+
-+			file_map.put( key, file_additional_properties.get( key ));
-+		}
-+	
-+		return file_map;
-+	}
-+			
- }
-+
-+
-diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java
-index 1fb54dd..676244d 100644
---- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java
-+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java
-@@ -409,45 +409,10 @@ TOTorrentImpl
- 				
- 				TOTorrentFileImpl	file	= files[i];
- 				
--				Map	file_map = new HashMap();
-+				Map	file_map = file.serializeToMap();
- 		
- 				meta_files.add( file_map );
- 				
--				file_map.put( TK_LENGTH, new Long( file.getLength()));
--				
--				List path = new ArrayList();
--				
--				file_map.put( TK_PATH, path );
--				
--				byte[][]	path_comps = file.getPathComponents();
--				
--				for (int j=0;j<path_comps.length;j++){
--					
--					path.add( path_comps[j]);
--				}
--				
--				if ( file.isUTF8()){
--					
--					List utf8_path = new ArrayList();
--					
--					file_map.put( TK_PATH_UTF8, utf8_path );
--										
--					for (int j=0;j<path_comps.length;j++){
--						
--						utf8_path.add( path_comps[j]);
--					}
--				}
--				
--				Map file_additional_properties = file.getAdditionalProperties();
--				
--				Iterator prop_it = file_additional_properties.keySet().iterator();
--				
--				while( prop_it.hasNext()){
--					
--					String	key = (String)prop_it.next();
--					
--					file_map.put( key, file_additional_properties.get( key ));
--				}
- 			}
- 		}
- 		
-@@ -505,6 +470,14 @@ TOTorrentImpl
- 	{
- 		torrent_name	= _name;
- 	}
-+
-+	protected void
-+	setNameUTF8(
-+		byte[] _name)
-+	{
-+		torrent_name_utf8	= _name;
-+	}
-+		
- 	
- 	public boolean
- 	isSimpleTorrent()
-@@ -1264,4 +1237,4 @@ TOTorrentImpl
- 
- 		return null;
- 	}
--}
-\ No newline at end of file
-+}
--- 
-tg: (320870a..) fixes/utf8-encoding (depends on: upstream)
diff --git a/debian/patches/series b/debian/patches/series
index e9ad5e8..095156b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,8 +1,6 @@
 debian/speedtest.diff -p1
 debian/update-disable.diff -p1
 fixes/encoding.diff -p1
-fixes/multi-announce-deadlock.diff -p1
 fixes/multiuser.diff -p1
 fixes/platform.diff -p1
 fixes/sunsecurity.diff -p1
-fixes/utf8-encoding.diff -p1
diff --git a/debian/rules b/debian/rules
index 9384b6a..309beda 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,7 +1,6 @@
 #!/usr/bin/make -f
 # -*- makefile -*-
 
-include /usr/share/cdbs/1/rules/patchsys-quilt.mk
 include /usr/share/cdbs/1/rules/debhelper.mk
 include /usr/share/cdbs/1/class/ant.mk
 -include /usr/share/topgit/tg2quilt.mk
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/org/gudy/azureus2/core3/config/COConfigurationManager.java b/org/gudy/azureus2/core3/config/COConfigurationManager.java
index b12c66b..229b59b 100644
--- a/org/gudy/azureus2/core3/config/COConfigurationManager.java
+++ b/org/gudy/azureus2/core3/config/COConfigurationManager.java
@@ -102,7 +102,13 @@ COConfigurationManager
 			      //fixes the osx kernel panic bug caused by Apple's faulty kqueue implementation (as of 10.3.6)
 			  	
 			    if( Constants.isOSX ) {
-			        System.setProperty( "java.nio.preferSelect", "true" );
+			    	
+			    		// things seem good in 10.6
+			    	
+			    	if ( !Constants.isOSX_10_6_OrHigher ){
+			        
+			    		System.setProperty( "java.nio.preferSelect", "true" );
+			    	}
 			    }
 			    
 			    SystemProperties.determineApplicationName();
diff --git a/org/gudy/azureus2/core3/config/impl/ConfigurationDefaults.java b/org/gudy/azureus2/core3/config/impl/ConfigurationDefaults.java
index cd5af5a..abff61f 100644
--- a/org/gudy/azureus2/core3/config/impl/ConfigurationDefaults.java
+++ b/org/gudy/azureus2/core3/config/impl/ConfigurationDefaults.java
@@ -383,10 +383,10 @@ public class ConfigurationDefaults {
     def.put( "Tracker Server Not Found Redirect", "" );
     def.put( "Tracker Server Support Experimental Extensions", FALSE );
     
-    def.put( "Network Selection Prompt", TRUE);
-    def.put( "Network Selection Default.Public", TRUE);
-    def.put( "Network Selection Default.I2P", TRUE);
-    def.put( "Network Selection Default.Tor", TRUE);
+    def.put( "Network Selection Prompt", FALSE );
+    def.put( "Network Selection Default.Public", TRUE );
+    def.put( "Network Selection Default.I2P", FALSE );
+    def.put( "Network Selection Default.Tor", FALSE );
     def.put( "Tracker Network Selection Default.Public", TRUE);
     def.put( "Tracker Network Selection Default.I2P", TRUE);
     def.put( "Tracker Network Selection Default.Tor", TRUE);
@@ -398,6 +398,7 @@ public class ConfigurationDefaults {
     def.put( "Peer Source Selection Default.Incoming", TRUE);
     
     def.put( "config.style.useSIUnits", FALSE );
+    def.put( "config.style.forceSIValues", Constants.isOSX_10_6_OrHigher?FALSE:TRUE );
     def.put( "config.style.useUnitsRateBits", FALSE );
     def.put( "config.style.separateProtDataStats", FALSE );
     def.put( "config.style.dataStatsOnly", FALSE );
diff --git a/org/gudy/azureus2/core3/disk/DiskManager.java b/org/gudy/azureus2/core3/disk/DiskManager.java
index 7b87619..e645a44 100644
--- a/org/gudy/azureus2/core3/disk/DiskManager.java
+++ b/org/gudy/azureus2/core3/disk/DiskManager.java
@@ -25,6 +25,7 @@ package org.gudy.azureus2.core3.disk;
 import java.io.File;
 
 import org.gudy.azureus2.core3.disk.impl.piecemapper.DMPieceList;
+import org.gudy.azureus2.core3.disk.impl.piecemapper.DMPieceMap;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.DirectByteBuffer;
 import org.gudy.azureus2.core3.util.IndentWriter;
@@ -179,6 +180,13 @@ DiskManager
 	public DiskManagerFileInfoSet getFileSet();
 	public DiskManagerPiece getPiece(int PieceNumber);
 
+		/**
+		 * DON'T CACHE the DMPieceMap - as it is designed to be discarded when not in use
+		 * @return
+		 */
+	
+	public DMPieceMap  getPieceMap();
+	
 	public DMPieceList getPieceList(int pieceNumber);
 	
 	public int
diff --git a/org/gudy/azureus2/core3/disk/impl/DiskManagerImpl.java b/org/gudy/azureus2/core3/disk/impl/DiskManagerImpl.java
index ebeeb57..f3171eb 100644
--- a/org/gudy/azureus2/core3/disk/impl/DiskManagerImpl.java
+++ b/org/gudy/azureus2/core3/disk/impl/DiskManagerImpl.java
@@ -1582,9 +1582,8 @@ DiskManagerImpl
 		return( reader.getStats());
 	}
 	
-	public DMPieceList
-	getPieceList(
-		int	piece_number )
+	public DMPieceMap  
+	getPieceMap()
 	{
 		DMPieceMap	map = piece_map_use_accessor;
 		
@@ -1597,6 +1596,15 @@ DiskManagerImpl
 		
 		piece_map_use_accessor_time = SystemTime.getCurrentTime();
 
+		return( map );
+	}
+	
+	public DMPieceList
+	getPieceList(
+		int	piece_number )
+	{
+		DMPieceMap	map = getPieceMap();
+
 		return( map.getPieceList( piece_number ));
 	}
 		
diff --git a/org/gudy/azureus2/core3/disk/impl/access/impl/DMCheckerImpl.java b/org/gudy/azureus2/core3/disk/impl/access/impl/DMCheckerImpl.java
index 59c1292..9cad18d 100644
--- a/org/gudy/azureus2/core3/disk/impl/access/impl/DMCheckerImpl.java
+++ b/org/gudy/azureus2/core3/disk/impl/access/impl/DMCheckerImpl.java
@@ -602,7 +602,7 @@ DMCheckerImpl
 			return;
 		}
 		
-		int	pieceNumber	= request.getPieceNumber();
+		final int	pieceNumber	= request.getPieceNumber();
 		
 		try{
 			
@@ -617,7 +617,7 @@ DMCheckerImpl
 				// three pieces as it is possible that these were once complete and have all their bits
 				// living in retained compact areas
 			
-			DMPieceList pieceList = disk_manager.getPieceList(pieceNumber);
+			final DMPieceList pieceList = disk_manager.getPieceList(pieceNumber);
 
 			try{
 					// there are other comments in the code about the existence of 0 length piece lists
@@ -756,6 +756,31 @@ DMCheckerImpl
 					    					}finally{
 					    						
 					    						try{
+					    							if ( async_result == 1 ){
+					    							
+					    								try{
+					    									for (int i = 0; i < pieceList.size(); i++) {
+					    										
+					    										DMPieceMapEntry piece_entry = pieceList.get(i);
+					    											
+					    										DiskManagerFileInfoImpl	file_info = piece_entry.getFile();
+					    										
+					    										CacheFile	cache_file = file_info.getCacheFile();
+					    										
+					    										cache_file.setPieceComplete( pieceNumber, f_buffer );
+					    									}
+					    								}catch( Throwable e ){
+					    									
+					    									f_buffer.returnToPool();
+					    									
+					    									Debug.out( e );
+					    									
+					    									listener.checkFailed( request, e );
+					    									
+					    									return;
+					    								}
+					    							}
+					    							
 						    						f_buffer.returnToPool();
 	
 						    						if ( async_result == 1 ){
diff --git a/org/gudy/azureus2/core3/disk/impl/piecemapper/impl/PieceMapperImpl.java b/org/gudy/azureus2/core3/disk/impl/piecemapper/impl/PieceMapperImpl.java
index 6a9eec4..fc5d482 100644
--- a/org/gudy/azureus2/core3/disk/impl/piecemapper/impl/PieceMapperImpl.java
+++ b/org/gudy/azureus2/core3/disk/impl/piecemapper/impl/PieceMapperImpl.java
@@ -271,54 +271,29 @@ PieceMapperImpl
 			return( new DMPieceMapImpl( pieceMap ));
 		}
 	}
-
 	
-
 	private List<PieceMapEntryImpl> 
 	buildLastPieceToFileList(
 		List<fileInfo> 	file_list, 
-		int 			currentFile, 
-		long 			fileOffset )
+		int 			current_file, 
+		long 			file_offset )
 	{
-		int piece_length	= (int)torrent.getPieceLength();
-	
-		ArrayList<PieceMapEntryImpl> pieceToFileList = new ArrayList<PieceMapEntryImpl>();
-		int usedSpace = 0;
-		while (last_piece_length > usedSpace) {
-			fileInfo tempFile = file_list.get(currentFile);
-			long length = tempFile.getLength();
-
-			//get the available space
-			long availableSpace = length - fileOffset;
-
-			PieceMapEntryImpl tempPieceEntry = null;
-
-			//how much space do we need to use?                               
-			if (availableSpace <= (piece_length - usedSpace)) {
-				//use the rest of the file's space
-				tempPieceEntry = new PieceMapEntryImpl(tempFile.getFileInfo(), fileOffset, (int)availableSpace);
+		ArrayList<PieceMapEntryImpl> piece_to_file_list = new ArrayList<PieceMapEntryImpl>();
 
-				//update the used space
-				usedSpace += availableSpace;
-				//update the file offset
-				fileOffset = 0;
-				//move the the next file
-				currentFile++;
-			} else //we don't need to use the whole file
-				{
-				tempPieceEntry = new PieceMapEntryImpl(tempFile.getFileInfo(), fileOffset, last_piece_length - usedSpace);
-
-				//update the file offset
-				fileOffset += piece_length - usedSpace;
-				//udate the used space
-				usedSpace += piece_length - usedSpace;
-			}
+		for ( int i=current_file;i<file_list.size();i++){
+			
+			fileInfo file = file_list.get( i );
+						
+			long space_in_file = file.getLength() - file_offset;
+			
+			PieceMapEntryImpl piece_entry = new PieceMapEntryImpl( file.getFileInfo(), file_offset, (int)space_in_file);
 
-			//add the temp pieceEntry to the piece list
-			pieceToFileList.add(tempPieceEntry);
+			piece_to_file_list.add( piece_entry );
+			
+			file_offset = 0;
 		}
-
-		return pieceToFileList;
+		
+		return( piece_to_file_list );
 	}
 
 	public long
diff --git a/org/gudy/azureus2/core3/download/DownloadManager.java b/org/gudy/azureus2/core3/download/DownloadManager.java
index 40d8bba..3f917e9 100644
--- a/org/gudy/azureus2/core3/download/DownloadManager.java
+++ b/org/gudy/azureus2/core3/download/DownloadManager.java
@@ -685,6 +685,13 @@ DownloadManager
      */
     public void renameTorrent(String new_name) throws DownloadManagerException;
 
+
+		/**
+		 * Same as renameTorrent, but appends numbers if torrent already exists 
+		 * @since 4.2.0.9
+		 */
+		public void renameTorrentSafe(String name) throws DownloadManagerException;
+    
     /**
      * @since 3.0.5.1
      */
diff --git a/org/gudy/azureus2/core3/download/DownloadManagerState.java b/org/gudy/azureus2/core3/download/DownloadManagerState.java
index 24eb92c..990289c 100644
--- a/org/gudy/azureus2/core3/download/DownloadManagerState.java
+++ b/org/gudy/azureus2/core3/download/DownloadManagerState.java
@@ -62,12 +62,14 @@ DownloadManagerState
 	public static final String AT_AVAIL_BAD_TIME			= "badavail";
 	public static final String AT_TIME_STOPPED				= "timestopped";
 	public static final String AT_INCOMP_FILE_SUFFIX		= "incompfilesuffix";
+	public static final String AT_SCRAPE_CACHE				= "scrapecache";	// long value, seeds in upper word, leechers in lower
 	
 	public static Object[][] ATTRIBUTE_DEFAULTS = {
 		{ AT_VERSION,								new Integer( -1 )},
 		{ AT_TIME_SINCE_DOWNLOAD,					new Integer( -1 )},
 		{ AT_TIME_SINCE_UPLOAD,						new Integer( -1 )},
 		{ AT_AVAIL_BAD_TIME,						new Long( -1 )},
+		{ AT_SCRAPE_CACHE,							new Long( -1 )},
 	};
 	
 	public static final long FLAG_ONLY_EVER_SEEDED						= Download.FLAG_ONLY_EVER_SEEDED;
@@ -130,6 +132,9 @@ DownloadManagerState
 	getFlag(
 		long		flag );
 	
+	public long
+	getFlags();
+
 		/**
 		 * Reset to default value
 		 * @param name
diff --git a/org/gudy/azureus2/core3/download/impl/DownloadManagerController.java b/org/gudy/azureus2/core3/download/impl/DownloadManagerController.java
index 6f3b024..c47251e 100644
--- a/org/gudy/azureus2/core3/download/impl/DownloadManagerController.java
+++ b/org/gudy/azureus2/core3/download/impl/DownloadManagerController.java
@@ -27,7 +27,6 @@ import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.util.*;
 
-
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.disk.*;
 import org.gudy.azureus2.core3.download.DownloadManager;
@@ -331,12 +330,12 @@ DownloadManagerController
 	    			public long
 	    			getTotalSent()
 	    			{
-	    				return(temp.getStats().getTotalDataBytesSent());
+	    				return(temp.getStats().getTotalDataBytesSentNoLan());
 	    			}
 	    			public long
 	    			getTotalReceived()
 	    			{
-	    				long received 	= temp.getStats().getTotalDataBytesReceived();
+	    				long received 	= temp.getStats().getTotalDataBytesReceivedNoLan();
 	    				long discarded 	= temp.getStats().getTotalDiscarded();
 	    				long failed		= temp.getStats().getTotalHashFailBytes();
 	    				
@@ -2182,7 +2181,7 @@ DownloadManagerController
 			// too early in initialisation sequence to action this - it'll get reinvoked later anyway
 			if (info.length == 0) return;
 			
-			final List delayed_prio_changes = new ArrayList();
+			final List delayed_prio_changes = new ArrayList(0);
 			
 			try {
 				this_mon.enter();
diff --git a/org/gudy/azureus2/core3/download/impl/DownloadManagerImpl.java b/org/gudy/azureus2/core3/download/impl/DownloadManagerImpl.java
index 7439cea..b8e58cb 100644
--- a/org/gudy/azureus2/core3/download/impl/DownloadManagerImpl.java
+++ b/org/gudy/azureus2/core3/download/impl/DownloadManagerImpl.java
@@ -2017,6 +2017,14 @@ DownloadManagerImpl
 			
 			// Need to notify listeners, even if scrape result is not valid, in
 			// case they parse invalid scrapes 
+			
+			if ( response.isValid() && response.getStatus() == TRTrackerScraperResponse.ST_ONLINE ){
+			
+				long cache = ((((long)response.getSeeds())&0x00ffffffL)<<32)|(((long)response.getPeers())&0x00ffffffL);
+				
+				download_manager_state.setLongAttribute( DownloadManagerState.AT_SCRAPE_CACHE, cache );
+			}
+			
 			tracker_listeners.dispatch(LDT_TL_SCRAPERESULT, response);
 		}
 	}
@@ -3749,7 +3757,7 @@ DownloadManagerImpl
 		this.moveTorrentFile(null, name);
 	}
 
-	private void renameTorrentSafe(String name) throws DownloadManagerException {
+	public void renameTorrentSafe(String name) throws DownloadManagerException {
 		String torrent_parent = new File(this.getTorrentFileName()).getParent();
 		String torrent_name = name;
 		
diff --git a/org/gudy/azureus2/core3/download/impl/DownloadManagerStateImpl.java b/org/gudy/azureus2/core3/download/impl/DownloadManagerStateImpl.java
index a586e34..05aa6c5 100644
--- a/org/gudy/azureus2/core3/download/impl/DownloadManagerStateImpl.java
+++ b/org/gudy/azureus2/core3/download/impl/DownloadManagerStateImpl.java
@@ -24,7 +24,6 @@ package org.gudy.azureus2.core3.download.impl;
 
 import java.io.*;
 import java.net.URL;
-import java.security.SecureRandom;
 import java.util.*;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.GZIPOutputStream;
@@ -35,11 +34,7 @@ import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.disk.DiskManagerFactory;
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.download.DownloadManagerState;
-import org.gudy.azureus2.core3.download.DownloadManagerStateAttributeListener;
-import org.gudy.azureus2.core3.download.DownloadManagerStateEvent;
-import org.gudy.azureus2.core3.download.DownloadManagerStateListener;
+import org.gudy.azureus2.core3.download.*;
 import org.gudy.azureus2.core3.logging.LogEvent;
 import org.gudy.azureus2.core3.logging.LogIDs;
 import org.gudy.azureus2.core3.logging.LogRelation;
@@ -117,7 +112,7 @@ DownloadManagerStateImpl
 	
 	private static Map					state_map 					= new HashMap();
 	private static Map					global_state_cache			= new HashMap();
-	private static List					global_state_cache_wrappers	= new ArrayList();
+	private static ArrayList			global_state_cache_wrappers	= new ArrayList();
 	
 	private DownloadManagerImpl			download_manager;
 	
@@ -471,6 +466,7 @@ DownloadManagerStateImpl
 		}
 		
 		global_state_cache_wrappers.clear();
+		global_state_cache_wrappers.trimToSize();
 	}
 
 	protected
@@ -885,6 +881,12 @@ DownloadManagerStateImpl
 		return(( value & flag ) != 0 );
 	}
 	
+	public long 
+	getFlags() 
+	{
+		return( getLongAttribute( AT_FLAGS ));
+	}
+	
 	public boolean parameterExists(String name) {
 		return parameters.containsKey(name);
 	}
@@ -1239,10 +1241,14 @@ DownloadManagerStateImpl
 			if (fileInfo.length > 0) {
 				int idxBiggest = -1;
 				long lBiggest = -1;
-				for (int i = 0; i < fileInfo.length && i < 10; i++) {
-					if (!fileInfo[i].isSkipped() && fileInfo[i].getLength() > lBiggest) {
-						lBiggest = fileInfo[i].getLength();
-						idxBiggest = i;
+				int numChecked = 0;
+				for (int i = 0; i < fileInfo.length && numChecked < 10; i++) {
+					if (!fileInfo[i].isSkipped()) {
+						numChecked++;
+						if (fileInfo[i].getLength() > lBiggest) {
+  						lBiggest = fileInfo[i].getLength();
+  						idxBiggest = i;
+						}
 					}
 				}
 				if (idxBiggest >= 0) {
@@ -2393,6 +2399,12 @@ DownloadManagerStateImpl
 			return( false );
 		}
 		
+		public long 
+		getFlags() 
+		{
+			return 0;
+		}
+		
 		public void
 		setParameterDefault(
 			String	name )
@@ -3272,6 +3284,16 @@ DownloadManagerStateImpl
 	   		return( null );
     	}
     	
+       	public void
+    	setCreatedBy(
+    		byte[]		cb )
+       	{
+	   		if ( fixup()){
+				
+				delegate.setCreatedBy( cb );
+			}
+    	}
+       	
     	public boolean
     	isCreated()
        	{
diff --git a/org/gudy/azureus2/core3/global/impl/GlobalManagerImpl.java b/org/gudy/azureus2/core3/global/impl/GlobalManagerImpl.java
index 82a4a4f..ac89054 100644
--- a/org/gudy/azureus2/core3/global/impl/GlobalManagerImpl.java
+++ b/org/gudy/azureus2/core3/global/impl/GlobalManagerImpl.java
@@ -409,6 +409,32 @@ public class GlobalManagerImpl
     			return( false );
     		}
     		
+    		public int[] 
+    		getCachedScrape(
+    			HashWrapper hash )
+    		{
+    			DownloadManager	dm = getDownloadManager(hash);
+    			
+    			if ( dm == null ){
+    				
+    				return( null );
+    			}
+    						
+				long cache = dm.getDownloadState().getLongAttribute( DownloadManagerState.AT_SCRAPE_CACHE );
+				
+				if ( cache == -1 ){
+					
+					return( null );
+					
+				}else{
+					
+					int seeds 		= (int)((cache>>32)&0x00ffffff);
+					int leechers 	= (int)(cache&0x00ffffff);
+					
+					return( new int[]{ seeds, leechers });
+				}
+    		}
+    		
     		public Object[]
     		getExtensions(
     			HashWrapper	hash )
diff --git a/org/gudy/azureus2/core3/internat/LocaleTorrentUtil.java b/org/gudy/azureus2/core3/internat/LocaleTorrentUtil.java
index e80bc57..dc8f207 100644
--- a/org/gudy/azureus2/core3/internat/LocaleTorrentUtil.java
+++ b/org/gudy/azureus2/core3/internat/LocaleTorrentUtil.java
@@ -61,6 +61,9 @@ public class LocaleTorrentUtil
 		if (encoding == null) {
 			return null;
 		}
+		if (TOTorrent.ENCODING_ACTUALLY_UTF8_KEYS.equals(encoding)) {
+			encoding = "utf8";
+		}
 
 		// get canonical name
 
@@ -106,6 +109,9 @@ public class LocaleTorrentUtil
 		throws TOTorrentException, UnsupportedEncodingException
 	{
 		String encoding = torrent.getAdditionalStringProperty("encoding");
+		if (TOTorrent.ENCODING_ACTUALLY_UTF8_KEYS.equals(encoding)) {
+			encoding = "utf8";
+		}
 
 		// we can only persist the torrent if it has a filename defined for it
 
diff --git a/org/gudy/azureus2/core3/internat/MessageText.java b/org/gudy/azureus2/core3/internat/MessageText.java
index 816f30c..8358049 100644
--- a/org/gudy/azureus2/core3/internat/MessageText.java
+++ b/org/gudy/azureus2/core3/internat/MessageText.java
@@ -24,7 +24,6 @@ import java.io.FilenameFilter;
 import java.net.URI;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.security.AccessController;
 import java.util.*;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
@@ -39,13 +38,13 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.FileUtil;
 import org.gudy.azureus2.core3.util.SystemProperties;
 
-import sun.security.action.GetPropertyAction;
 
 /**
  * @author Arbeiten
  * 
  * @author CrazyAlchemist Added keyExistsForDefaultLocale
  */
+ at SuppressWarnings("restriction")
 public class MessageText {
 
   public static final Locale LOCALE_ENGLISH = Constants.LOCALE_ENGLISH;
@@ -763,16 +762,16 @@ public class MessageText {
  * Reverts Locale back to default, and removes the config settin. 
  * Notifications of change should be done by the caller.
  */
-  public static void revertToDefaultLocale() {
+  /*
+  @SuppressWarnings("restriction")
+	public static void revertToDefaultLocale() {
   	// Aside from the last 2 lines, this is Sun's code that is run
   	// at startup to determine the locale.  Too bad they didn't provide
   	// a way to call this code explicitly..
     String language, region, country, variant;
-    language = (String) AccessController.doPrivileged(
-                    new GetPropertyAction("user.language", "en"));
+    language = System.getProperty("user.language", "en");
     // for compatibility, check for old user.region property
-    region = (String) AccessController.doPrivileged(
-                    new GetPropertyAction("user.region"));
+    region = System.getProperty("user.region");
     if (region != null) {
         // region can be of form country, country_variant, or _variant
         int i = region.indexOf('_');
@@ -784,14 +783,13 @@ public class MessageText {
             variant = "";
         }
     } else {
-        country = (String) AccessController.doPrivileged(
-                        new GetPropertyAction("user.country", ""));
-        variant = (String) AccessController.doPrivileged(
-                        new GetPropertyAction("user.variant", ""));
+        country = System.getProperty("user.country", "");
+        variant = System.getProperty("user.variant", "");
     }
     changeLocale(new Locale(language, country, variant));
     COConfigurationManager.removeParameter("locale");
   }
+  */
   
   public static interface
   MessageTextListener
diff --git a/org/gudy/azureus2/core3/peer/PEPeer.java b/org/gudy/azureus2/core3/peer/PEPeer.java
index 81a49c7..eed5f15 100644
--- a/org/gudy/azureus2/core3/peer/PEPeer.java
+++ b/org/gudy/azureus2/core3/peer/PEPeer.java
@@ -26,6 +26,8 @@
 package org.gudy.azureus2.core3.peer;
 
 
+import java.net.InetAddress;
+
 import org.gudy.azureus2.plugins.network.Connection;
 
 import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
@@ -88,6 +90,11 @@ PEPeer
 	public byte[] getId();
 
 	public String getIp();
+	
+	/**
+	 * @return an ipv6 address under which the peer should be connectable if it announced one, null otherwise
+	 */
+	public InetAddress getAlternativeIPv6();
   
   /**
    * Get the peer's local TCP connection port.
diff --git a/org/gudy/azureus2/core3/peer/PEPeerManagerStats.java b/org/gudy/azureus2/core3/peer/PEPeerManagerStats.java
index f8e05ad..28bae6d 100644
--- a/org/gudy/azureus2/core3/peer/PEPeerManagerStats.java
+++ b/org/gudy/azureus2/core3/peer/PEPeerManagerStats.java
@@ -49,6 +49,12 @@ PEPeerManagerStats
   	public long getTotalDataBytesReceived();
   	public long getTotalProtocolBytesReceived();
   
+	public long getTotalDataBytesSentNoLan();
+	public long getTotalProtocolBytesSentNoLan();
+  
+  	public long getTotalDataBytesReceivedNoLan();
+  	public long getTotalProtocolBytesReceivedNoLan();
+
 	public long getTotalAverage();
 
 	public long getTotalHashFailBytes();
diff --git a/org/gudy/azureus2/core3/peer/impl/PEPeerManagerStatsImpl.java b/org/gudy/azureus2/core3/peer/impl/PEPeerManagerStatsImpl.java
index 9743c29..f840481 100644
--- a/org/gudy/azureus2/core3/peer/impl/PEPeerManagerStatsImpl.java
+++ b/org/gudy/azureus2/core3/peer/impl/PEPeerManagerStatsImpl.java
@@ -37,6 +37,12 @@ PEPeerManagerStatsImpl
 	private long total_data_bytes_sent = 0;
 	private long total_protocol_bytes_sent = 0;
 	  
+	private long total_data_bytes_received_lan = 0;
+	private long total_protocol_bytes_received_lan = 0;
+  
+	private long total_data_bytes_sent_lan = 0;
+	private long total_protocol_bytes_sent_lan = 0;
+
 	private long totalDiscarded;
 	private long hash_fail_bytes;
 
@@ -81,6 +87,9 @@ PEPeerManagerStatsImpl
 	
 	public void dataBytesReceived( PEPeer peer, int length) {
 	  total_data_bytes_received += length;
+	  if ( peer.isLANLocal()){
+		  total_data_bytes_received_lan += length;
+	  }
 	  data_receive_speed.addValue(length);
 	  
 	  if ( length > 0 ){
@@ -92,6 +101,9 @@ PEPeerManagerStatsImpl
 
   public void protocolBytesReceived(PEPeer peer, int length) {
     total_protocol_bytes_received += length;
+	  if ( peer.isLANLocal()){
+		  total_protocol_bytes_received_lan += length;
+	  }
     protocol_receive_speed.addValue(length);
     
     adapter.protocolBytesReceived( peer, length );
@@ -100,6 +112,9 @@ PEPeerManagerStatsImpl
   
 	public void dataBytesSent(PEPeer peer, int length ) {
 	  total_data_bytes_sent += length;
+	  if ( peer.isLANLocal()){
+		  total_data_bytes_sent_lan += length;
+	  }
 	  data_send_speed.addValue(length);  
 	  
 	  if ( length > 0 ){
@@ -111,6 +126,9 @@ PEPeerManagerStatsImpl
   
   public void protocolBytesSent(PEPeer peer, int length) {
     total_protocol_bytes_sent += length;
+	  if ( peer.isLANLocal()){
+		  total_protocol_bytes_sent_lan += length;
+	  }
     protocol_send_speed.addValue(length);
     
  	adapter.protocolBytesSent( peer, length );
@@ -125,19 +143,18 @@ PEPeerManagerStatsImpl
 	  return( data_receive_speed.getAverage());
 	}
 
-  public long getProtocolReceiveRate() {
-    return protocol_receive_speed.getAverage();
-  }
+	public long getProtocolReceiveRate() {
+		return protocol_receive_speed.getAverage();
+	}
   
   
 	public long getDataSendRate() {
 	  return( data_send_speed.getAverage());
 	}
   
-  public long getProtocolSendRate() {
-    return protocol_send_speed.getAverage();
-  }
-  
+	public long getProtocolSendRate() {
+		return protocol_send_speed.getAverage();
+	}
   
 	public long getTotalDiscarded() {
 	  return( totalDiscarded );
@@ -163,7 +180,24 @@ PEPeerManagerStatsImpl
     return total_protocol_bytes_received;
   }
   
-    
+	public long getTotalDataBytesSentNoLan()
+	{
+		return( Math.max( total_data_bytes_sent - total_data_bytes_sent_lan, 0 ));
+	}
+	public long getTotalProtocolBytesSentNoLan()
+	{
+		return( Math.max( total_protocol_bytes_sent - total_protocol_bytes_sent_lan, 0 ));
+	}
+  	public long getTotalDataBytesReceivedNoLan()
+	{
+  		return( Math.max( total_data_bytes_received - total_data_bytes_received_lan, 0 ));
+  	}
+  	public long getTotalProtocolBytesReceivedNoLan()
+	{
+  		return( Math.max( total_protocol_bytes_received - total_protocol_bytes_received_lan, 0 ));
+	}
+
+
 	public long 
 	getTotalAverage() 
 	{
diff --git a/org/gudy/azureus2/core3/peer/impl/PEPeerTransport.java b/org/gudy/azureus2/core3/peer/impl/PEPeerTransport.java
index c9e7efb..1a5259a 100644
--- a/org/gudy/azureus2/core3/peer/impl/PEPeerTransport.java
+++ b/org/gudy/azureus2/core3/peer/impl/PEPeerTransport.java
@@ -222,11 +222,12 @@ PEPeerTransport
 		/**
 		 * Attempts to reconnect to the same peer
 		 * @param tryUDP try to initate a UDP connection if true, just reestablish the previous state otherwise
+		 * @param tryIPv6 TODO
 		 * @return null if reconnect not possible, reconnected peer otherwise
 		 */
 	
 	public PEPeerTransport
-	reconnect(boolean tryUDP);
+	reconnect(boolean tryUDP, boolean tryIPv6);
 	
 	/**
 	 * This method is called to check if it is safe to reconnect to a peer, i.e. avoid hammering
diff --git a/org/gudy/azureus2/core3/peer/impl/control/PEPeerControlImpl.java b/org/gudy/azureus2/core3/peer/impl/control/PEPeerControlImpl.java
index fc935ad..5657c49 100644
--- a/org/gudy/azureus2/core3/peer/impl/control/PEPeerControlImpl.java
+++ b/org/gudy/azureus2/core3/peer/impl/control/PEPeerControlImpl.java
@@ -23,35 +23,50 @@
 package org.gudy.azureus2.core3.peer.impl.control;
 
 
+import java.net.Inet6Address;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
 import java.util.*;
 
-import org.gudy.azureus2.core3.config.*;
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.disk.*;
 import org.gudy.azureus2.core3.ipfilter.*;
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.core3.peer.*;
 import org.gudy.azureus2.core3.peer.impl.*;
-import org.gudy.azureus2.core3.peer.util.*;
+import org.gudy.azureus2.core3.peer.util.PeerIdentityDataID;
+import org.gudy.azureus2.core3.peer.util.PeerIdentityManager;
+import org.gudy.azureus2.core3.peer.util.PeerUtils;
 import org.gudy.azureus2.core3.torrent.TOTorrentException;
-import org.gudy.azureus2.core3.tracker.client.*;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerResponse;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerResponsePeer;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.download.DownloadAnnounceResultPeer;
 import org.gudy.azureus2.plugins.peers.Peer;
 import org.gudy.azureus2.plugins.peers.PeerDescriptor;
 
 import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
 import com.aelitis.azureus.core.networkmanager.impl.tcp.TCPConnectionManager;
 import com.aelitis.azureus.core.networkmanager.impl.tcp.TCPNetworkManager;
 import com.aelitis.azureus.core.networkmanager.impl.udp.UDPNetworkManager;
-import com.aelitis.azureus.core.peermanager.control.*;
+import com.aelitis.azureus.core.peermanager.control.PeerControlInstance;
+import com.aelitis.azureus.core.peermanager.control.PeerControlScheduler;
+import com.aelitis.azureus.core.peermanager.control.PeerControlSchedulerFactory;
 import com.aelitis.azureus.core.peermanager.nat.PeerNATInitiator;
 import com.aelitis.azureus.core.peermanager.nat.PeerNATTraversalAdapter;
 import com.aelitis.azureus.core.peermanager.nat.PeerNATTraverser;
 import com.aelitis.azureus.core.peermanager.peerdb.*;
-import com.aelitis.azureus.core.peermanager.piecepicker.*;
-import com.aelitis.azureus.core.peermanager.unchoker.*;
+import com.aelitis.azureus.core.peermanager.piecepicker.PiecePicker;
+import com.aelitis.azureus.core.peermanager.piecepicker.PiecePickerFactory;
+import com.aelitis.azureus.core.peermanager.unchoker.Unchoker;
+import com.aelitis.azureus.core.peermanager.unchoker.UnchokerFactory;
+import com.aelitis.azureus.core.peermanager.unchoker.UnchokerUtil;
 import com.aelitis.azureus.core.peermanager.uploadslots.UploadHelper;
 import com.aelitis.azureus.core.peermanager.uploadslots.UploadSlotManager;
 import com.aelitis.azureus.core.util.FeatureAvailability;
@@ -790,7 +805,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 			for( int i=0; i < peer_transports.size(); i++ ) {
 				final PEPeerTransport peer = (PEPeerTransport)peer_transports.get( i );
 
-				PEPeerTransport	reconnected_peer = peer.reconnect(false);
+				PEPeerTransport	reconnected_peer = peer.reconnect(false, false);
 			}
 		}
 	}
@@ -2479,6 +2494,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 		boolean	connection_found = false;
 		
 		boolean tcpReconnect = false;
+		boolean ipv6reconnect = false;
 		
 		try{
 			peer_transports_mon.enter();
@@ -2486,15 +2502,29 @@ DiskManagerCheckRequestListener, IPFilterListener
 			int udpPort = peer.getUDPListenPort();
 			
 			boolean canTryUDP = UDPNetworkManager.UDP_OUTGOING_ENABLED && peer.getUDPListenPort() > 0;
+			boolean canTryIpv6 = NetworkAdmin.getSingleton().hasIPV6Potential(true) && peer.getAlternativeIPv6() != null;
 
 			if ( is_running ){
 
 				PeerItem peer_item = peer.getPeerItemIdentity();
 				PeerItem self_item = peer_database.getSelfPeer();
+				
 
 				if ( self_item == null || !self_item.equals( peer_item )){
 
 					String	ip = peer.getIp();
+					boolean wasIPv6;
+					try
+					{
+						wasIPv6 = InetAddress.getByName(ip) instanceof Inet6Address;
+					} catch (UnknownHostException e)
+					{
+						wasIPv6 = false;
+						// something is fishy about the old address, don't try to reconnect with v6
+						canTryIpv6 = false;
+					}
+					
+					//System.out.println("netfail="+network_failed+", connfail="+connect_failed+", can6="+canTryIpv6+", was6="+wasIPv6);
 					
 					String	key = ip + ":" + udpPort;
 
@@ -2507,7 +2537,11 @@ DiskManagerCheckRequestListener, IPFilterListener
 							if ( canTryUDP && udp_fallback_for_failed_connection ){
 								
 								pending_nat_traversals.put(key, peer);
-							}					
+							} else if (canTryIpv6 && !wasIPv6)
+							{
+								tcpReconnect = true;
+								ipv6reconnect = true;
+							}
 						}else if ( 	canTryUDP && 
 									udp_fallback_for_dropped_connection && 
 									network_failed && 
@@ -2571,7 +2605,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 		}
 		
 		if(tcpReconnect)
-			peer.reconnect(false);
+			peer.reconnect(false, ipv6reconnect);
 	}
 
 
@@ -3791,6 +3825,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 		if ( mainloop_loop_count % MAINLOOP_THIRTY_SECOND_INTERVAL == 0 ) {
 			//if we're at our connection limit, time out the least-useful
 			//one so we can establish a possibly-better new connection
+			optimisticDisconnectCount = 0;
 			if( getMaxNewConnectionsAllowed() == 0 ) {  //we've reached limit        
 				doOptimisticDisconnect( false, false );
 			}
@@ -3815,7 +3850,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 
 		nextPEXSweepIndex = goal;
 	}
-
+	
 	private void
 	doUDPConnectionChecks(
 		int		number )
@@ -3911,7 +3946,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 							{
 								complete();
 								
-								PEPeerTransport newTransport = peer.reconnect(true);
+								PEPeerTransport newTransport = peer.reconnect(true, false);
 								
 								if( newTransport != null ){
 									
@@ -3957,15 +3992,19 @@ DiskManagerCheckRequestListener, IPFilterListener
 					PEPeerTransport	peer_item = (PEPeerTransport)new_connections.get(i);
 
 						// don't call when holding monitor - deadlock potential
-					peer_item.reconnect(true);
+					peer_item.reconnect(true, false);
 
 				}
 			}
 		}
 	}
+	
+	// counter is reset every 30s by doConnectionChecks()
+	private int optimisticDisconnectCount = 0;
 
 	public boolean doOptimisticDisconnect( boolean	pending_lan_local_peer, boolean force )
 	{
+		
 		final ArrayList peer_transports = peer_transports_cow;
 		PEPeerTransport max_transport = null;
 		PEPeerTransport max_seed_transport		= null;
@@ -3974,6 +4013,9 @@ DiskManagerCheckRequestListener, IPFilterListener
 		long max_time = 0;
 		long max_seed_time 		= 0;
 		long max_non_lan_time	= 0;
+		
+
+		List<Long> activeConnectionTimes = new ArrayList<Long>(peer_transports.size());
 
 		int	lan_peer_count	= 0;
 
@@ -3981,15 +4023,19 @@ DiskManagerCheckRequestListener, IPFilterListener
 			final PEPeerTransport peer = (PEPeerTransport)peer_transports.get( i );
 
 			if( peer.getConnectionState() == PEPeerTransport.CONNECTION_FULLY_ESTABLISHED ) {
-				final long timeSinceSentData =peer.getTimeSinceLastDataMessageSent();
 
+				final long timeSinceConnection =peer.getTimeSinceConnectionEstablished();
+				final long timeSinceSentData =peer.getTimeSinceLastDataMessageSent();				
+				
+				activeConnectionTimes.add(timeSinceConnection);
+				
 				long peerTestTime = 0;
 				if( seeding_mode){
 					if( timeSinceSentData != -1 )
 						peerTestTime = timeSinceSentData;  //ensure we've sent them at least one data message to qualify for drop
 				}else{
 					final long timeSinceGoodData =peer.getTimeSinceGoodDataReceived();
-					final long timeSinceConnection =peer.getTimeSinceConnectionEstablished();
+					
 
 					if( timeSinceGoodData == -1 ) 
 						peerTestTime +=timeSinceConnection;   //never received
@@ -4037,29 +4083,31 @@ DiskManagerCheckRequestListener, IPFilterListener
 
 					PEPeerStats pestats = peer.getStats();
 					// everybody has deserverd a chance of half an MB transferred data
-					if(pestats.getTotalDataBytesReceived()+pestats.getTotalDataBytesSent() < 1024*512 ) {
+					if(pestats.getTotalDataBytesReceived()+pestats.getTotalDataBytesSent() > 1024*512 ) {
+						boolean goodPeer = true;
+						
 						// we don't like snubbed peers with a negative gain
 						if( peer.isSnubbed() && pestats.getTotalDataBytesReceived() < pestats.getTotalDataBytesSent() ) {
 							peerTestTime *= 1.5;
+							goodPeer = false;
 						}
 						// we don't like peers with a very bad ratio (10:1)
 						if( pestats.getTotalDataBytesSent() > pestats.getTotalDataBytesReceived() * 10 ) {
 							peerTestTime *= 2;
+							goodPeer = false;
 						}
 						// modify based on discarded : overall downloaded ratio
-						if( pestats.getTotalDataBytesReceived() > 0  ) {
+						if( pestats.getTotalDataBytesReceived() > 0 && pestats.getTotalBytesDiscarded() > 0 ) {
 							peerTestTime = (long)(peerTestTime *( 1.0+((double)pestats.getTotalBytesDiscarded()/(double)pestats.getTotalDataBytesReceived())));
 						}
+						
+						// prefer peers that do some work, let the churn happen with peers that did nothing
+						if(goodPeer)
+							peerTestTime *= 0.7;							
 					}
 				}
 
 
-
-
-
-
-
-
 				if( peerTestTime > max_time ) {
 					max_time = peerTestTime;
 					max_transport = peer;
@@ -4074,7 +4122,24 @@ DiskManagerCheckRequestListener, IPFilterListener
 				}
 			}
 		}
-
+		
+		long medianConnectionTime;
+		
+		if ( activeConnectionTimes.size() > 0 ){
+			Collections.sort(activeConnectionTimes);
+			medianConnectionTime = activeConnectionTimes.get(activeConnectionTimes.size()/2);
+		}else{
+			medianConnectionTime = 0;
+		}
+		
+		// allow 1 disconnect every 30s per 30 peers; 2 at least every 30s
+		int maxOptimistics = Math.max(getMaxConnections()/30,2);
+		
+		// avoid unnecessary churn, e.g. 
+		if(!pending_lan_local_peer && !force && optimisticDisconnectCount >= maxOptimistics && medianConnectionTime < 5*60*1000)
+			return false;
+		
+		
 		// don't boot lan peers if we can help it (unless we have a few of them)
 
 		if ( max_transport != null ){
@@ -4093,11 +4158,13 @@ DiskManagerCheckRequestListener, IPFilterListener
 
 			if( getMaxSeedConnections() > 0 && max_seed_transport != null && max_time > 5*60*1000 ) {
 				closeAndRemovePeer( max_seed_transport, "timed out by doOptimisticDisconnect()", true );
+				optimisticDisconnectCount++;
 				return true;
 			}
 
 			if( max_transport != null && max_time > 5 *60*1000 ) {  //ensure a 5 min minimum test time
 				closeAndRemovePeer( max_transport, "timed out by doOptimisticDisconnect()", true );
+				optimisticDisconnectCount++;
 				return true;
 			}
 
@@ -4105,6 +4172,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 
 			if ( pending_lan_local_peer && lan_peer_count < LAN_PEER_MAX ){
 				closeAndRemovePeer( max_transport, "making space for LAN peer in doOptimisticDisconnect()", true );
+				optimisticDisconnectCount++;
 				return true;
 			}
 			
diff --git a/org/gudy/azureus2/core3/peer/impl/transport/PEPeerTransportProtocol.java b/org/gudy/azureus2/core3/peer/impl/transport/PEPeerTransportProtocol.java
index a4b6098..79514bf 100644
--- a/org/gudy/azureus2/core3/peer/impl/transport/PEPeerTransportProtocol.java
+++ b/org/gudy/azureus2/core3/peer/impl/transport/PEPeerTransportProtocol.java
@@ -21,9 +21,9 @@
 package org.gudy.azureus2.core3.peer.impl.transport;
 
 
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
-import java.security.SecureRandom;
 import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
@@ -47,6 +47,7 @@ import org.gudy.azureus2.pluginsimpl.local.network.ConnectionImpl;
 
 import com.aelitis.azureus.core.impl.AzureusCoreImpl;
 import com.aelitis.azureus.core.networkmanager.*;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
 import com.aelitis.azureus.core.networkmanager.impl.tcp.ProtocolEndpointTCP;
 import com.aelitis.azureus.core.networkmanager.impl.tcp.TCPNetworkManager;
 import com.aelitis.azureus.core.networkmanager.impl.udp.ProtocolEndpointUDP;
@@ -91,6 +92,8 @@ implements PEPeerTransport
 	private int tcp_listen_port = 0;
 	private int udp_listen_port = 0;
 	private int udp_non_data_port = 0;
+	// if the peer announces an ipv6 address
+	private InetAddress alternativeAddress;
 
 	private byte	crypto_level;
 
@@ -847,7 +850,7 @@ implements PEPeerTransport
 			recentlyDisconnected.put(mySessionID, this);
 	}
 	
-	public PEPeerTransport reconnect(boolean tryUDP) {
+	public PEPeerTransport reconnect(boolean tryUDP, boolean tryIPv6) {
 		
 		boolean use_tcp = isTCP() && !(tryUDP && getUDPListenPort() > 0);
 		
@@ -859,7 +862,7 @@ implements PEPeerTransport
 				PEPeerTransportFactory.createTransport( 
 						manager, 
 						getPeerSource(), 
-						getIp(), 
+						tryIPv6 && alternativeAddress != null ? alternativeAddress.getHostAddress() : getIp(), 
 						getTCPListenPort(), 
 						getUDPListenPort(),
 						use_tcp,
@@ -873,6 +876,9 @@ implements PEPeerTransport
 			{
 				PEPeerTransportProtocol pt = (PEPeerTransportProtocol) new_conn;
 				pt.checkForReconnect(mySessionID);
+				// carry over the alt address in case the reconnect fails and we try again with ipv6
+				pt.alternativeAddress = alternativeAddress;
+
 			}
 			
 			manager.addPeer( new_conn );
@@ -1010,6 +1016,9 @@ implements PEPeerTransport
 		data_dict.put("p", new Integer(localTcpPort));
 		data_dict.put("e", new Long(require_crypto ? 1L : 0L));
 		data_dict.put("upload_only", new Long(manager.isSeeding() && !ENABLE_LAZY_BITFIELD ? 1L : 0L));
+		InetAddress defaultV6 = NetworkAdmin.getSingleton().hasIPV6Potential(true) ? NetworkAdmin.getSingleton().getDefaultPublicAddressV6() : null;
+		if(defaultV6 != null)
+			data_dict.put("ipv6",defaultV6.getAddress());
 		LTHandshake lt_handshake = new LTHandshake(
 				data_dict, other_peer_bt_lt_ext_version
 		);
@@ -1057,6 +1066,7 @@ implements PEPeerTransport
 				local_tcp_port,
 				local_udp_port,
 				local_udp2_port,
+				NetworkAdmin.getSingleton().hasIPV6Potential(true) ? NetworkAdmin.getSingleton().getDefaultPublicAddressV6() : null,
 				avail_ids,
 				avail_vers,
 				require_crypto ? AZHandshake.HANDSHAKE_TYPE_CRYPTO : AZHandshake.HANDSHAKE_TYPE_PLAIN,
@@ -1529,6 +1539,7 @@ implements PEPeerTransport
 
 	public byte[] getId() {  return peer_id;  }
 	public String getIp() {  return ip;  }
+	public InetAddress getAlternativeIPv6() { return alternativeAddress; }
 	public int getPort() {  return port;  }
 
 	public int getTCPListenPort() {  return tcp_listen_port;  }
@@ -2375,6 +2386,9 @@ implements PEPeerTransport
 		  relativeSeeding |= RELATIVE_SEEDING_UPLOAD_ONLY_INDICATED;
 		  checkSeed();
 	  }
+	  
+	  if(AddressUtils.isGlobalAddressV6(handshake.getIPv6()))
+		  alternativeAddress = handshake.getIPv6();
 		  
 	  
 	  
@@ -2421,6 +2435,9 @@ implements PEPeerTransport
 			// their random local port
 			peer_item_identity = PeerItemFactory.createPeerItem(ip, tcp_listen_port, PeerItem.convertSourceID(peer_source), type, udp_listen_port, crypto_level, 0);
 		}
+		
+		if(AddressUtils.isGlobalAddressV6(handshake.getIPv6()))
+			alternativeAddress = handshake.getIPv6();
 
 		
 		if(handshake.getReconnectSessionID() != null)
diff --git a/org/gudy/azureus2/core3/stats/impl/StatsWriterPeriodicImpl.java b/org/gudy/azureus2/core3/stats/impl/StatsWriterPeriodicImpl.java
index 04d3788..b71d9e6 100644
--- a/org/gudy/azureus2/core3/stats/impl/StatsWriterPeriodicImpl.java
+++ b/org/gudy/azureus2/core3/stats/impl/StatsWriterPeriodicImpl.java
@@ -21,15 +21,15 @@
  
 package org.gudy.azureus2.core3.stats.impl;
 
-import java.io.*;
+import java.io.File;
 
-import org.gudy.azureus2.core3.logging.*;
-import org.gudy.azureus2.core3.stats.*;
-import org.gudy.azureus2.core3.util.AEMonitor;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.SystemTime;
-import org.gudy.azureus2.core3.config.*;
-import org.gudy.azureus2.core3.util.AEThread;
+import org.gudy.azureus2.core3.config.COConfigurationListener;
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.logging.LogEvent;
+import org.gudy.azureus2.core3.logging.LogIDs;
+import org.gudy.azureus2.core3.logging.Logger;
+import org.gudy.azureus2.core3.stats.StatsWriterPeriodic;
+import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.AzureusCore;
 /**
@@ -38,41 +38,31 @@ import com.aelitis.azureus.core.AzureusCore;
 
 public class 
 StatsWriterPeriodicImpl 
-	implements StatsWriterPeriodic, COConfigurationListener
+	implements StatsWriterPeriodic, COConfigurationListener, TimerEventPerformer
 {
 	private static final LogIDs LOGID = LogIDs.CORE; 
 	
 	private static StatsWriterPeriodicImpl	singleton;
-	private static AEMonitor				class_mon	= new AEMonitor( "StatsWriterPeriodic" );
 		
-	private static int				start_count;
-	private static Thread			current_thread;
+	private boolean started;
 	
 	private long			last_write_time	= 0;
 	private AzureusCore		core;
 	
+	private TimerEventPeriodic event;
 	private boolean			config_enabled;
 	private int				config_period;	
 	private String			config_dir;
 	private String			config_file;
 	
-	public static StatsWriterPeriodic
-	create(
-		AzureusCore		_core )
-	{
-		try{
-			class_mon.enter();
-		
-			if ( singleton == null ){
-				
+	public static synchronized StatsWriterPeriodic create(AzureusCore _core) {
+		synchronized (StatsWriterPeriodicImpl.class)
+		{
+			if (singleton == null)
+			{
 				singleton = new StatsWriterPeriodicImpl(_core);
 			}
-			
-			return( singleton );
-			
-		}finally{
-			
-			class_mon.exit();
+			return (singleton);
 		}
 	}
 	
@@ -81,63 +71,25 @@ StatsWriterPeriodicImpl
 		AzureusCore		_core )
 	{
 		core	= _core;
-		
-		COConfigurationManager.addListener( this );	
+	}
+	
+
+	public void perform(TimerEvent event) {
+		update();
 	}
 	
 	protected void
 	update()
 	{
-		readConfigValues();
-		
-		while( true ){
-									
-			try{
-				class_mon.enter();
-				
-				if ( Thread.currentThread() != current_thread ){
-					
-					break;
-				}
-				
-				writeStats();	
-				
-			}catch( Throwable e ){
-				
-				Debug.printStackTrace(e );
-				
-			}finally{
-				
-				class_mon.exit();
-			}
-			
-			try{
-				int	period;
-				
-				if ( !config_enabled ){
-					
-					period = DEFAULT_SLEEP_PERIOD;
-								
-				}else{
-				
-				 	period = config_period*1000;
-				}
-				
-				if ( period > DEFAULT_SLEEP_PERIOD ){
-					
-					period = DEFAULT_SLEEP_PERIOD;
-				}
-				
-				Thread.sleep( period );
-				
-			}catch( InterruptedException e ){
-				
-				Debug.printStackTrace( e );
-			}
+		try {
+			writeStats();
+		} catch (Throwable e)
+		{
+			Debug.printStackTrace(e);
 		}
 	}
 	
-	protected void
+	protected synchronized void
 	readConfigValues()
 	{
 		config_enabled 	= COConfigurationManager.getBooleanParameter( "Stats Enable" );
@@ -147,6 +99,27 @@ StatsWriterPeriodicImpl
 		config_dir		= COConfigurationManager.getStringParameter( "Stats Dir" );
 		
 		config_file		= COConfigurationManager.getStringParameter( "Stats File" );
+		
+		if(config_enabled)
+		{
+			long targetFrequency = 1000 * (config_period < DEFAULT_SLEEP_PERIOD ? config_period : DEFAULT_SLEEP_PERIOD); 
+			if(event != null && event.getFrequency() != targetFrequency)
+			{
+				event.cancel();
+				event = null;
+			}
+			
+			if(event == null)
+				event = SimpleTimer.addPeriodicEvent("StatsWriter", targetFrequency, this);
+			
+		} else if(event != null)
+		{
+			event.cancel();
+			event = null;
+		}
+
+
+		
 	}
 	
 	protected void
@@ -159,11 +132,8 @@ StatsWriterPeriodicImpl
 
 		int	period = config_period;
 		
-		long	now = SystemTime.getCurrentTime() /1000;
+		long	now = SystemTime.getMonotonousTime() /1000;
         
-        if( now < last_write_time ) {  //time went backwards
-          last_write_time   = now;
-        }
 		
 			// if we have a 1 second period then now-last-write_time will often be 0 (due to the
 			// rounding of SystemTime) and the stats won't be written - hence the check against
@@ -225,49 +195,21 @@ StatsWriterPeriodicImpl
 	public void
 	start()
 	{
-		try{
-			class_mon.enter();
-			
-			start_count++;
-			
-			if ( start_count == 1 ){
-							
-				current_thread = 
-					new AEThread("StatsWriter"){
-						public void
-						runSupport()
-						{
-							update();
-						}
-					};
-					
-				current_thread.setDaemon( true );
-				
-				current_thread.start();
-			}
-		}finally{
-			
-			class_mon.exit();
-		}
+		if(started)
+			return;
+		started = true;
+		COConfigurationManager.addListener( this );	
+		configurationSaved();
 	}
 	
 	public void
 	stop()
 	{
-		try{
-			class_mon.enter();
-			
-			start_count--;
-			
-			if ( start_count == 0 ){
-				
-				current_thread = null;
-			}
-		}finally{
-			
-			class_mon.exit();
-		}
+		COConfigurationManager.removeListener( this );	
+		if(event != null)
+			event.cancel();
 	}
+
 	
 
 }
diff --git a/org/gudy/azureus2/core3/stats/transfer/impl/OverallStatsImpl.java b/org/gudy/azureus2/core3/stats/transfer/impl/OverallStatsImpl.java
index c236bf8..6a4aa8e 100644
--- a/org/gudy/azureus2/core3/stats/transfer/impl/OverallStatsImpl.java
+++ b/org/gudy/azureus2/core3/stats/transfer/impl/OverallStatsImpl.java
@@ -50,7 +50,9 @@ OverallStatsImpl
   
   private static final long TEN_YEARS 		= 60*60*24*365*10L;
   
-  private static final long	STATS_PERIOD	= 60*1000;	// 1 min
+  private static final int	STATS_PERIOD	= 60*1000;		// 1 min
+  private static final int	SAVE_PERIOD		= 10*60*1000;	// 10 min
+  private static final int	SAVE_TICKS		= SAVE_PERIOD / STATS_PERIOD;
   
   private AzureusCore	core;
    
@@ -174,34 +176,37 @@ OverallStatsImpl
 				Map		values )
 			{	
 			  	try{
-				    GlobalManagerStats stats = core.getGlobalManager().getStats();
-
 			  		this_mon.enter();
 			  		
-					if ( types.contains( AzureusCoreStats.ST_XFER_UPLOADED_PROTOCOL_BYTES )){
-						
-						values.put( 
-							AzureusCoreStats.ST_XFER_UPLOADED_PROTOCOL_BYTES, 
-							new Long( totalProtocolUploaded + ( stats.getTotalProtocolBytesSent() - lastProtocolUploaded )));
-					}
-					if ( types.contains( AzureusCoreStats.ST_XFER_UPLOADED_DATA_BYTES )){
-						
-						values.put( 
-							AzureusCoreStats.ST_XFER_UPLOADED_DATA_BYTES, 
-							new Long( totalDataUploaded + ( stats.getTotalDataBytesSent() - lastDataUploaded )));
-					}
-					if ( types.contains( AzureusCoreStats.ST_XFER_DOWNLOADED_PROTOCOL_BYTES )){
-						
-						values.put( 
-							AzureusCoreStats.ST_XFER_DOWNLOADED_PROTOCOL_BYTES, 
-							new Long( totalProtocolDownloaded + ( stats.getTotalProtocolBytesReceived() - lastProtocolDownloaded )));
-					}
-					if ( types.contains( AzureusCoreStats.ST_XFER_DOWNLOADED_DATA_BYTES )){
-						
-						values.put( 
-							AzureusCoreStats.ST_XFER_DOWNLOADED_DATA_BYTES, 
-							new Long( totalDataDownloaded + ( stats.getTotalDataBytesReceived() - lastDataDownloaded )));
-					}
+			  		if ( core.isStarted()){
+			  			
+					    GlobalManagerStats stats = core.getGlobalManager().getStats();
+	
+						if ( types.contains( AzureusCoreStats.ST_XFER_UPLOADED_PROTOCOL_BYTES )){
+							
+							values.put( 
+								AzureusCoreStats.ST_XFER_UPLOADED_PROTOCOL_BYTES, 
+								new Long( totalProtocolUploaded + ( stats.getTotalProtocolBytesSent() - lastProtocolUploaded )));
+						}
+						if ( types.contains( AzureusCoreStats.ST_XFER_UPLOADED_DATA_BYTES )){
+							
+							values.put( 
+								AzureusCoreStats.ST_XFER_UPLOADED_DATA_BYTES, 
+								new Long( totalDataUploaded + ( stats.getTotalDataBytesSent() - lastDataUploaded )));
+						}
+						if ( types.contains( AzureusCoreStats.ST_XFER_DOWNLOADED_PROTOCOL_BYTES )){
+							
+							values.put( 
+								AzureusCoreStats.ST_XFER_DOWNLOADED_PROTOCOL_BYTES, 
+								new Long( totalProtocolDownloaded + ( stats.getTotalProtocolBytesReceived() - lastProtocolDownloaded )));
+						}
+						if ( types.contains( AzureusCoreStats.ST_XFER_DOWNLOADED_DATA_BYTES )){
+							
+							values.put( 
+								AzureusCoreStats.ST_XFER_DOWNLOADED_DATA_BYTES, 
+								new Long( totalDataDownloaded + ( stats.getTotalDataBytesReceived() - lastDataDownloaded )));
+						}
+			  		}
 			  	}finally{
 			  	  	
 			  		this_mon.exit();
@@ -342,9 +347,7 @@ OverallStatsImpl
 	    
 	    totalUptime += delta;
 	    lastUptime = current_time;
-	    
-	    tick_count++;
-    
+	        
 	    HashMap	overallMap = new HashMap();
 	    
 	    overallMap.put("downloaded",new Long(totalDownloaded));
@@ -360,7 +363,12 @@ OverallStatsImpl
 	    
 	    map.put( "all", overallMap );
 	    
-	    save( map );
+	    tick_count++;
+
+	    if ( force || tick_count % SAVE_TICKS == 0 ){
+	    
+	    	save( map );
+	    }
   	}finally{
   	
   		this_mon.exit();
diff --git a/org/gudy/azureus2/core3/torrent/TOTorrent.java b/org/gudy/azureus2/core3/torrent/TOTorrent.java
index df5c21d..3115869 100644
--- a/org/gudy/azureus2/core3/torrent/TOTorrent.java
+++ b/org/gudy/azureus2/core3/torrent/TOTorrent.java
@@ -44,7 +44,9 @@ TOTorrent
 		 */
 	
 	public static final String	AZUREUS_PRIVATE_PROPERTIES		= "azureus_private_properties";
-	
+
+	public static final String ENCODING_ACTUALLY_UTF8_KEYS = "utf8 keys";
+
 	/**
 	 * Get the name of the torrent
 	 * @return
@@ -89,6 +91,10 @@ TOTorrent
 	public byte[]
 	getCreatedBy();
 	
+	public void
+	setCreatedBy(
+		byte[]		cb );
+	
 	public boolean
 	isCreated();
 	
diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java
index 510d2ce..a20d6b9 100644
--- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java
+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java
@@ -467,6 +467,8 @@ TOTorrentDeserialiseImpl
 												TOTorrentException.RT_DECODE_FAILS ));
 			}
 		
+			boolean hasUTF8Keys = info.containsKey(TK_NAME_UTF8);
+			
 			setName((byte[])info.get( TK_NAME ));
 				
 			long	piece_length = ((Long)info.get( TK_PIECE_LENGTH )).longValue();
@@ -485,11 +487,19 @@ TOTorrentDeserialiseImpl
 			
 			long	total_length = 0;
 			
+			String encoding = getAdditionalStringProperty("encoding");
+			hasUTF8Keys &= encoding == null || encoding.equals(ENCODING_ACTUALLY_UTF8_KEYS);
+			
 			if ( simple_file_length != null ){
 			
 				setSimpleTorrent( true );
 				
 				total_length = simple_file_length.longValue();
+
+				if (hasUTF8Keys) {
+					setNameUTF8((byte[])info.get( TK_NAME_UTF8 ));
+					setAdditionalStringProperty("encoding", ENCODING_ACTUALLY_UTF8_KEYS);
+				}
 				
 				setFiles( new TOTorrentFileImpl[]{ new TOTorrentFileImpl( this, 0, total_length, new byte[][]{getName()})});
 				
@@ -500,7 +510,23 @@ TOTorrentDeserialiseImpl
 				List	meta_files = (List)info.get( TK_FILES );
 			
 				TOTorrentFileImpl[] files = new TOTorrentFileImpl[ meta_files.size()];
-			
+
+				if (hasUTF8Keys) {
+  				for (int i=0;i<files.length;i++){
+  					Map	file_map = (Map)meta_files.get(i);
+  					
+  					hasUTF8Keys &= file_map.containsKey(TK_PATH_UTF8);
+  					if (!hasUTF8Keys) {
+  						break;
+  					}
+  				}
+
+  				if (hasUTF8Keys) {
+  					setNameUTF8((byte[])info.get( TK_NAME_UTF8 ));
+  					setAdditionalStringProperty("encoding", ENCODING_ACTUALLY_UTF8_KEYS);
+  				}
+				}
+				
 				for (int i=0;i<files.length;i++){
 					
 					Map	file_map = (Map)meta_files.get(i);
@@ -508,7 +534,8 @@ TOTorrentDeserialiseImpl
 					long	len = ((Long)file_map.get( TK_LENGTH )).longValue();
 					
 					List	paths = (List)file_map.get( TK_PATH );
-						
+					List	paths8 = (List)file_map.get( TK_PATH_UTF8 );
+					
 					byte[][]	path_comps = new byte[paths.size()][];
 					
 					for (int j=0;j<paths.size();j++){
@@ -516,7 +543,20 @@ TOTorrentDeserialiseImpl
 						path_comps[j] = (byte[])paths.get(j);
 					}
 					
-					TOTorrentFileImpl file = files[i] = new TOTorrentFileImpl( this, total_length, len, path_comps );
+					TOTorrentFileImpl file;
+
+					if (hasUTF8Keys) {
+  					byte[][]	path_comps8 = new byte[paths8.size()][];
+  					
+  					for (int j=0;j<paths8.size();j++){
+  					
+  						path_comps8[j] = (byte[])paths8.get(j);
+  					}
+					
+						file = files[i] = new TOTorrentFileImpl( this, total_length, len, path_comps, path_comps8 );
+					} else {
+						file = files[i] = new TOTorrentFileImpl( this, total_length, len, path_comps );
+					}
 					
 					total_length += len;
 					
@@ -532,6 +572,7 @@ TOTorrentDeserialiseImpl
 								key.equals( TK_PATH )){
 									
 							// standard
+							// we don't skip TK_PATH_UTF8 because some code might assume getAdditionalProperty can get it
 						}else{
 							
 							file.setAdditionalProperty( key, file_map.get( key ));
diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java
index 85d9359..af3877e 100644
--- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java
+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java
@@ -36,6 +36,7 @@ TOTorrentFileImpl
 	private final TOTorrent	torrent;
 	private final long		file_length;
 	private final byte[][]	path_components;
+	private final byte[][]	path_components_utf8;
 	
 	private final int		first_piece_number;
 	private final int		last_piece_number;
@@ -87,7 +88,11 @@ TOTorrentFileImpl
 			path_components		= new byte[temp.size()][];
 			
 			temp.copyInto( path_components );
+
+			path_components_utf8		= new byte[temp.size()][];
 			
+			temp.copyInto( path_components_utf8 );
+
 			checkComponents();
 			
 		}catch( UnsupportedEncodingException e ){
@@ -96,7 +101,7 @@ TOTorrentFileImpl
 											TOTorrentException.RT_UNSUPPORTED_ENCODING));
 		}
 	}
-	
+
 	protected
 	TOTorrentFileImpl(
 		TOTorrent		_torrent,
@@ -109,6 +114,30 @@ TOTorrentFileImpl
 		torrent				= _torrent;
 		file_length			= _len;
 		path_components		= _path_components;
+		path_components_utf8 = null;
+		
+		first_piece_number 	= (int)( _torrent_offset / torrent.getPieceLength());
+		last_piece_number	= (int)(( _torrent_offset + file_length - 1 ) /  torrent.getPieceLength());
+
+		is_utf8				= false;
+		
+		checkComponents();
+	}
+
+	protected
+	TOTorrentFileImpl(
+		TOTorrent		_torrent,
+		long			_torrent_offset,
+		long			_len,
+		byte[][]		_path_components,
+		byte[][]		_path_components_utf8 )
+	
+		throws TOTorrentException
+	{
+		torrent				= _torrent;
+		file_length			= _len;
+		path_components		= _path_components;
+		path_components_utf8 = _path_components_utf8;
 		
 		first_piece_number 	= (int)( _torrent_offset / torrent.getPieceLength());
 		last_piece_number	= (int)(( _torrent_offset + file_length - 1 ) /  torrent.getPieceLength());
@@ -148,11 +177,24 @@ TOTorrentFileImpl
 	}
 	
 	public byte[][]
-	getPathComponents()
+	getPathComponentsBasic()
 	{
 		return( path_components );
 	}
+
+	public byte[][]
+	getPathComponents()
+	{
+		return path_components_utf8 == null ? path_components : path_components_utf8;
+	}
+
+	public byte[][]
+	getPathComponentsUTF8()
+	{
+		return( path_components_utf8 );
+	}
 	
+
 	protected boolean
 	isUTF8()
 	{
@@ -208,22 +250,23 @@ TOTorrentFileImpl
 		}
 
 		if (decoder != null) {
-			for (int j = 0; j < path_components.length; j++) {
+			byte[][]components = getPathComponents();
+			for (int j = 0; j < components.length; j++) {
 
 				try {
 					String comp;
 					try {
-						comp = decoder.decodeString(path_components[j]);
+						comp = decoder.decodeString(components[j]);
 					} catch (UnsupportedEncodingException e) {
 						System.out.println("file - unsupported encoding!!!!");
 						try {
-							comp = new String(path_components[j]);
+							comp = new String(components[j]);
 						} catch (Exception e2) {
 							comp = "UnsupportedEncoding";
 						}
 					}
 	
-					comp = FileUtil.convertOSSpecificChars(comp, j != path_components.length-1 );
+					comp = FileUtil.convertOSSpecificChars(comp, j != components.length-1 );
 	
 					sRelativePath += (j == 0 ? "" : File.separator) + comp;
 				} catch (Exception ex) {
@@ -235,4 +278,65 @@ TOTorrentFileImpl
 		}
 		return sRelativePath;
 	}
+
+	/**
+	 * @return
+	 *
+	 * @since 4.1.0.5
+	 */
+	public Map serializeToMap() {
+		Map	file_map = new HashMap();
+
+		file_map.put( TOTorrentImpl.TK_LENGTH, new Long( getLength()));
+		
+		List path = new ArrayList();
+		
+		file_map.put( TOTorrentImpl.TK_PATH, path );
+		
+		byte[][]	path_comps = getPathComponentsBasic();
+		
+		for (int j=0;j<path_comps.length;j++){
+			
+			path.add( path_comps[j]);
+		}
+		
+		if ( isUTF8()){
+			
+			List utf8_path = new ArrayList();
+			
+			file_map.put( TOTorrentImpl.TK_PATH_UTF8, utf8_path );
+								
+			for (int j=0;j<path_comps.length;j++){
+				
+				utf8_path.add( path_comps[j]);
+			}
+		} else {
+			
+			byte[][]	utf8_path_comps = getPathComponentsUTF8();
+
+			if (utf8_path_comps != null) {
+  			List utf8_path = new ArrayList();
+  			
+  			file_map.put( TOTorrentImpl.TK_PATH_UTF8, utf8_path );
+  								
+  			for (int j=0;j<utf8_path_comps.length;j++){
+  				
+  				utf8_path.add( utf8_path_comps[j]);
+  			}
+			}
+		}
+		
+		Map file_additional_properties = getAdditionalProperties();
+		
+		Iterator prop_it = file_additional_properties.keySet().iterator();
+		
+		while( prop_it.hasNext()){
+			
+			String	key = (String)prop_it.next();
+			
+			file_map.put( key, file_additional_properties.get( key ));
+		}
+
+		return file_map;
+	}
 }
diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java
index 1fb54dd..4c0eab6 100644
--- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java
+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java
@@ -228,8 +228,13 @@ TOTorrentImpl
 			
             bos.flush();
 			
-            fos.getFD().sync();
+		  		// thinking about removing this - just do so for CVS for the moment
+			  
+			if ( !Constants.isCVSVersion()){
             
+				fos.getFD().sync();
+			}
+			
             bos.close();
             
             bos = null;
@@ -409,45 +414,10 @@ TOTorrentImpl
 				
 				TOTorrentFileImpl	file	= files[i];
 				
-				Map	file_map = new HashMap();
+				Map	file_map = file.serializeToMap();
 		
 				meta_files.add( file_map );
 				
-				file_map.put( TK_LENGTH, new Long( file.getLength()));
-				
-				List path = new ArrayList();
-				
-				file_map.put( TK_PATH, path );
-				
-				byte[][]	path_comps = file.getPathComponents();
-				
-				for (int j=0;j<path_comps.length;j++){
-					
-					path.add( path_comps[j]);
-				}
-				
-				if ( file.isUTF8()){
-					
-					List utf8_path = new ArrayList();
-					
-					file_map.put( TK_PATH_UTF8, utf8_path );
-										
-					for (int j=0;j<path_comps.length;j++){
-						
-						utf8_path.add( path_comps[j]);
-					}
-				}
-				
-				Map file_additional_properties = file.getAdditionalProperties();
-				
-				Iterator prop_it = file_additional_properties.keySet().iterator();
-				
-				while( prop_it.hasNext()){
-					
-					String	key = (String)prop_it.next();
-					
-					file_map.put( key, file_additional_properties.get( key ));
-				}
 			}
 		}
 		
@@ -506,6 +476,13 @@ TOTorrentImpl
 		torrent_name	= _name;
 	}
 	
+	protected void
+	setNameUTF8(
+		byte[]	_name )
+	{
+		torrent_name_utf8	= _name;
+	}
+	
 	public boolean
 	isSimpleTorrent()
 	{
@@ -579,7 +556,7 @@ TOTorrentImpl
 		creation_date 	= _creation_date;
 	}
 	
-	protected void
+	public void
 	setCreatedBy(
 		byte[]		_created_by )
 	{
diff --git a/org/gudy/azureus2/core3/torrentdownloader/impl/TorrentDownloaderImpl.java b/org/gudy/azureus2/core3/torrentdownloader/impl/TorrentDownloaderImpl.java
index 7fd92a6..13974b1 100644
--- a/org/gudy/azureus2/core3/torrentdownloader/impl/TorrentDownloaderImpl.java
+++ b/org/gudy/azureus2/core3/torrentdownloader/impl/TorrentDownloaderImpl.java
@@ -33,6 +33,8 @@ import java.net.URL;
 import java.net.URLDecoder;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.InflaterInputStream;
 
 import javax.net.ssl.*;
 
@@ -419,7 +421,7 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
         			while( true ){
         				
         				try{
-        					Thread.sleep(250);
+        					Thread.sleep(100);
         					
         					try{
         						this_mon.enter();
@@ -434,11 +436,45 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
         					}
         					
         					String	s = con.getResponseMessage();
-        					        					
+        					  
         					if ( !s.equals( getStatus())){
         						
         						if ( !s.toLowerCase().startsWith("error:")){
         							
+        							if ( s.toLowerCase().indexOf( "alive" ) != -1 ){
+        								
+        								if ( percentDone < 10 ){
+        									
+        									percentDone++;
+        								}
+        							}
+        							
+        	     					int	pos = s.indexOf( '%' );
+                					
+                					if ( pos != -1 ){
+                						
+                						int	 i;
+                						
+                						for ( i=pos-1;i>=0;i--){
+                							
+                							char	c = s.charAt(i);
+                							
+                							if ( !Character.isDigit( c ) && c != ' ' ){
+                								
+                								i++;
+                								
+                								break;
+                							}
+                						}
+                						
+                						try{
+                							percentDone = Integer.parseInt( s.substring( i, pos ).trim());
+                							
+                						}catch( Throwable e ){
+                							
+                						}
+                					}
+                					
         							setStatus(s);
         							
         						}else{
@@ -448,6 +484,9 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
         						
         						changed_status	= true;
         					}
+   
+        					
+ 
         				}catch( Throwable e ){
         					
         					break;
@@ -492,6 +531,22 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
 			}
 		}
 			
+			// handle some servers that return gzip'd torrents even though we don't request it!
+		
+		String encoding = con.getHeaderField( "content-encoding");
+			
+		if ( encoding != null ){
+
+			if ( encoding.equalsIgnoreCase( "gzip" )){
+
+				in = new GZIPInputStream( in );
+
+			}else if ( encoding.equalsIgnoreCase( "deflate" )){
+
+				in = new InflaterInputStream( in );
+			}
+		}
+		
 	    if ( this.state != STATE_ERROR ){
 		    	
 	    	this.file = new File(this.directoryname, filename);
@@ -514,7 +569,7 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
 	        
 	        bufBytes = 0;
 	        
-	        int size = this.con.getContentLength();
+	        int size = (int) UrlUtils.getContentLength(con);
 	        
 			this.percentDone = -1;
 			
diff --git a/org/gudy/azureus2/core3/tracker/client/TRTrackerScraperClientResolver.java b/org/gudy/azureus2/core3/tracker/client/TRTrackerScraperClientResolver.java
index 02c33d1..5dfa23d 100644
--- a/org/gudy/azureus2/core3/tracker/client/TRTrackerScraperClientResolver.java
+++ b/org/gudy/azureus2/core3/tracker/client/TRTrackerScraperClientResolver.java
@@ -57,6 +57,16 @@ TRTrackerScraperClientResolver
 	getStatus(
 		HashWrapper	torrent_hash );
 	
+		/**
+		 * 
+		 * @param hash
+		 * @return
+		 */
+	
+	public int[]
+	getCachedScrape(
+		HashWrapper	hash );
+
 	public boolean
 	isNetworkEnabled(
 		HashWrapper	hash,
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperImpl.java
index d72a6ce..4277a2b 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperImpl.java
@@ -200,6 +200,12 @@ TRTrackerScraperImpl
 		client_resolver	= resolver;
 	}
 	
+	public TRTrackerScraperClientResolver
+	getClientResolver()
+	{
+		return( client_resolver );
+	}
+	
 	public boolean
 	isTorrentDownloading(
 		HashWrapper		hash )
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTAnnouncerImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTAnnouncerImpl.java
index 06676b4..25326ba 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTAnnouncerImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTAnnouncerImpl.java
@@ -21,39 +21,41 @@
 
 package org.gudy.azureus2.core3.tracker.client.impl.bt;
 
-import java.io.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
 import java.net.*;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Random;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-import javax.net.ssl.*;
-
-import java.util.zip.*;
-
-import org.gudy.azureus2.core3.logging.*;
-import org.gudy.azureus2.core3.config.*;
-import org.gudy.azureus2.core3.torrent.*;
-import org.gudy.azureus2.core3.security.*;
+import java.util.*;
+import java.util.zip.GZIPInputStream;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.logging.LogAlert;
+import org.gudy.azureus2.core3.logging.LogEvent;
+import org.gudy.azureus2.core3.logging.Logger;
+import org.gudy.azureus2.core3.peer.PEPeerSource;
+import org.gudy.azureus2.core3.security.SESecurityManager;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLSet;
+import org.gudy.azureus2.core3.torrent.TOTorrentException;
 import org.gudy.azureus2.core3.tracker.client.*;
 import org.gudy.azureus2.core3.tracker.client.impl.*;
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.core3.internat.*;
-//import org.gudy.azureus2.core3.peer.util.*;
-import org.gudy.azureus2.core3.peer.*;
-
-import org.gudy.azureus2.core3.tracker.protocol.*;
+import org.gudy.azureus2.core3.tracker.protocol.PRHelpers;
 import org.gudy.azureus2.core3.tracker.protocol.udp.*;
 import org.gudy.azureus2.core3.tracker.util.TRTrackerUtils;
-
-import org.gudy.azureus2.plugins.clientid.*;
-import org.gudy.azureus2.plugins.download.*;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.core3.util.Timer;
+import org.gudy.azureus2.plugins.clientid.ClientIDException;
+import org.gudy.azureus2.plugins.clientid.ClientIDGenerator;
+import org.gudy.azureus2.plugins.download.DownloadAnnounceResult;
+import org.gudy.azureus2.plugins.download.DownloadAnnounceResultPeer;
 import org.gudy.azureus2.pluginsimpl.local.clientid.ClientIDManagerImpl;
 
 import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPosition;
@@ -62,11 +64,7 @@ import com.aelitis.azureus.core.networkmanager.NetworkManager;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
 import com.aelitis.azureus.core.networkmanager.impl.udp.UDPNetworkManager;
 import com.aelitis.azureus.core.peermanager.utils.PeerClassifier;
-import com.aelitis.net.udp.uc.PRUDPPacket;
-import com.aelitis.net.udp.uc.PRUDPPacketHandler;
-import com.aelitis.net.udp.uc.PRUDPPacketHandlerException;
-import com.aelitis.net.udp.uc.PRUDPPacketHandlerFactory;
-import com.aelitis.net.udp.uc.PRUDPPacketRequest;
+import com.aelitis.net.udp.uc.*;
 
 
 /**
@@ -1074,6 +1072,8 @@ TRTrackerBTAnnouncerImpl
   		throws Exception
 	{
    			// set context in case authentication dialog is required
+ 		
+ 		boolean errorLevel = true;
     	
  		try{
 	    	TorrentUtils.setTLSTorrentHash( torrent_hash );
@@ -1209,6 +1209,9 @@ TRTrackerBTAnnouncerImpl
 					}
 				}catch( IOException e ){
 					
+					if(e instanceof UnknownHostException)
+						errorLevel = false;
+					
 		     		if ( i == 0 && protocol.toLowerCase().startsWith( "http" )){
 		      			
 		      			URL retry_url = UrlUtils.getIPV4Fallback( reqUrl );
@@ -1233,10 +1236,11 @@ TRTrackerBTAnnouncerImpl
 				if ( failure_reason != null && failure_reason.indexOf("401" ) != -1 ){
 						
 					failure_reason = "Tracker authentication failed";
+					errorLevel = false;
 				}
 			
 				if (Logger.isEnabled())
-					Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR,
+					Logger.log(new LogEvent(torrent, LOGID, errorLevel ? LogEvent.LT_ERROR : LogEvent.LT_WARNING,
 							"Exception while processing the Tracker Request for " + reqUrl + ": "
 									+ failure_reason));
 				
@@ -2382,6 +2386,12 @@ TRTrackerBTAnnouncerImpl
 								}
 								min_interval = 0;
 							}
+						} else {
+							// tracker owners complain we announce too much but then never
+							// implement "min interval".  So take it into our own hands
+							// and enforce a min_interval of interval when there is no
+							// "min interval"
+							min_interval = time_to_wait > 30 ? time_to_wait - 10 : time_to_wait;
 						}
 						
 						if(userMinInterval != 0)
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerChecker.java b/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerChecker.java
index 5b5eff8..367ab96 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerChecker.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerChecker.java
@@ -20,13 +20,20 @@
  */
 package org.gudy.azureus2.core3.tracker.client.impl.bt;
 
-import java.util.*;
-import java.net.*;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.logging.*;
-import org.gudy.azureus2.core3.torrent.*;
-import org.gudy.azureus2.core3.tracker.client.*;
+import org.gudy.azureus2.core3.logging.LogEvent;
+import org.gudy.azureus2.core3.logging.LogIDs;
+import org.gudy.azureus2.core3.logging.Logger;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLSet;
+import org.gudy.azureus2.core3.torrent.TOTorrentException;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
 import org.gudy.azureus2.core3.tracker.client.impl.TRTrackerScraperResponseImpl;
 import org.gudy.azureus2.core3.util.*;
 
@@ -34,7 +41,7 @@ import org.gudy.azureus2.core3.util.*;
  * @author Olivier
  * 
  */
-public class TrackerChecker implements AEDiagnosticsEvidenceGenerator, SystemTime.ChangeListener {
+public class TrackerChecker implements AEDiagnosticsEvidenceGenerator, SystemTime.ChangeListener, TimerEventPerformer {
 	private final static LogIDs LOGID = LogIDs.TRACKER;
 
   /** List of Trackers. 
@@ -64,15 +71,9 @@ public class TrackerChecker implements AEDiagnosticsEvidenceGenerator, SystemTim
     
     if ( !COConfigurationManager.getBooleanParameter("Tracker Client Scrape Total Disable")){
     	
-	    Thread t = new AEThread("Tracker Scrape") {
-	       public void runSupport() {
-	        runScrapes();
-	      }
-	    };
+	     runScrapes();
 	    
-	    t.setDaemon(true);
-	    t.setPriority(Thread.MIN_PRIORITY);
-	    t.start();
+
     }
   
     AEDiagnostics.addEvidenceGenerator( this );
@@ -288,15 +289,36 @@ public class TrackerChecker implements AEDiagnosticsEvidenceGenerator, SystemTim
   }
     
   
+	public void perform(TimerEvent event) {
+		runScrapes();
+	}
+  
   /** Loop indefinitely, waiting for the next scrape, and scraping.
    */
+	
+	TRTrackerBTScraperResponseImpl oldResponse;
+	
   private void 
   runScrapes() 
   {
-		TRTrackerBTScraperResponseImpl nextResponseScraping = null;
-
-		while (true) {
-
+		TRTrackerBTScraperResponseImpl nextResponseScraping = checkForNextScrape();
+
+		if (Logger.isEnabled() && nextResponseScraping != oldResponse && nextResponseScraping != null ) {
+			Logger.log(new LogEvent(
+					TorrentUtils.getDownloadManager(nextResponseScraping.getHash()),
+					LOGID,
+					LogEvent.LT_INFORMATION,
+					"Next scrape will be "
+							+ nextResponseScraping.getURL()
+							+ " in "
+							+ ((nextResponseScraping.getNextScrapeStartTime() - SystemTime.getCurrentTime())/1000)
+							+ " sec,type="
+							+ (nextResponseScraping.getTrackerStatus().getSupportsMultipeHashScrapes()
+									? "multi" : "single")
+									+ ",active="+nextResponseScraping.getTrackerStatus().getNumActiveScrapes()));
+		}
+		
+		
 			long delay;
 
 			if (nextResponseScraping == null) {
@@ -342,31 +364,11 @@ public class TrackerChecker implements AEDiagnosticsEvidenceGenerator, SystemTim
 				}
 			}
 
-			try {
-				nextScrapeCheckOn = SystemTime.getCurrentTime() + delay;
-				Thread.sleep(delay);
+			nextScrapeCheckOn = SystemTime.getCurrentTime() + delay;
+			oldResponse = nextResponseScraping;
+			// use tracker timer/thread pool
+			TRTrackerBTAnnouncerImpl.tracker_timer.addEvent(nextScrapeCheckOn, this);
 
-			} catch (Exception e) {
-			}
-
-			TRTrackerBTScraperResponseImpl oldResponse = nextResponseScraping;
-			nextResponseScraping = checkForNextScrape();
-
-			if (Logger.isEnabled() && nextResponseScraping != oldResponse && nextResponseScraping != null ) {
-				Logger.log(new LogEvent(
-						TorrentUtils.getDownloadManager(nextResponseScraping.getHash()),
-						LOGID,
-						LogEvent.LT_INFORMATION,
-						"Next scrape will be "
-								+ nextResponseScraping.getURL()
-								+ " in "
-								+ ((nextResponseScraping.getNextScrapeStartTime() - SystemTime.getCurrentTime())/1000)
-								+ " sec,type="
-								+ (nextResponseScraping.getTrackerStatus().getSupportsMultipeHashScrapes()
-										? "multi" : "single")
-										+ ",active="+nextResponseScraping.getTrackerStatus().getNumActiveScrapes()));
-			}
-		}
 	}
   
   /** Finds the torrent that will be needing a scrape next.
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerStatus.java b/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerStatus.java
index bad1981..31883c4 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerStatus.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerStatus.java
@@ -21,24 +21,23 @@
 package org.gudy.azureus2.core3.tracker.client.impl.bt;
 
 import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.FileNotFoundException;
 import java.net.*;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
+import java.util.*;
 import java.util.zip.GZIPInputStream;
 
-import javax.net.ssl.*;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.logging.*;
+import org.gudy.azureus2.core3.logging.LogEvent;
+import org.gudy.azureus2.core3.logging.LogIDs;
+import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.security.SESecurityManager;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperClientResolver;
@@ -863,6 +862,8 @@ public class TrackerStatus {
 				setAllError(e);
 			} catch (UnknownHostException e) {
 				setAllError(e);
+			} catch (PRUDPPacketHandlerException e) {
+				setAllError(e);
 			} catch (BEncodingException e) {
 				setAllError(e);
 			} catch (Exception e) {
@@ -946,8 +947,10 @@ public class TrackerStatus {
 		// Error will apply to ALL hashes, so set all
 		Object[] values;
 		try {
-			values = hashes.values().toArray();
 			hashes_mon.enter();
+			
+			values = hashes.values().toArray();
+
 		} finally {
 			hashes_mon.exit();
 		}
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTScraperImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTScraperImpl.java
index a963108..557b170 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTScraperImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTScraperImpl.java
@@ -25,14 +25,17 @@ package org.gudy.azureus2.core3.tracker.client.impl.dht;
 import java.util.*;
 import java.net.URL;
 
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.torrent.TOTorrentException;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperClientResolver;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
 import org.gudy.azureus2.core3.tracker.client.impl.TRTrackerScraperImpl;
-import org.gudy.azureus2.core3.tracker.client.impl.TRTrackerScraperResponseImpl;
 import org.gudy.azureus2.core3.util.AEMonitor;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.HashWrapper;
+import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.plugins.download.DownloadScrapeResult;
 
 /**
@@ -48,7 +51,7 @@ TRTrackerDHTScraperImpl
 
 	private TRTrackerScraperImpl		scraper;
 
-	private Map		responses = new HashMap();
+	private Map<HashWrapper,TRTrackerDHTScraperResponseImpl>		responses = new HashMap<HashWrapper,TRTrackerDHTScraperResponseImpl>();
 	
 	public static TRTrackerDHTScraperImpl
 	create(
@@ -86,7 +89,7 @@ TRTrackerDHTScraperImpl
 		if ( torrent != null && result != null){
 			
 			try{
-				TRTrackerScraperResponseImpl resp = 
+				TRTrackerDHTScraperResponseImpl resp = 
 					new TRTrackerDHTScraperResponseImpl( torrent.getHashWrapper(), result.getURL());
 							
 				resp.setSeedsPeers( result.getSeedCount(), result.getNonSeedCount());
@@ -115,13 +118,50 @@ TRTrackerDHTScraperImpl
 	public TRTrackerScraperResponse
 	scrape(
 		TOTorrent		torrent,
-		URL				target_url,
-		boolean			force )
+		URL				unused_target_url,
+		boolean			unused_force )
 	{
 		if ( torrent != null ){
 
 			try{
-				return((TRTrackerScraperResponse)responses.get( torrent.getHashWrapper()));
+				HashWrapper hw = torrent.getHashWrapper();
+				
+				TRTrackerDHTScraperResponseImpl response = responses.get( hw );
+				
+				if ( response == null ){
+					
+					TRTrackerScraperClientResolver resolver = scraper.getClientResolver();
+					
+					if ( resolver != null ){
+						
+						int[] cache = resolver.getCachedScrape( hw );
+						
+						if ( cache != null ){
+							
+							response = 
+								new TRTrackerDHTScraperResponseImpl( 
+										hw, torrent.getAnnounceURL());
+										
+							response.setSeedsPeers( cache[0], cache[1] );
+							
+							long now = SystemTime.getCurrentTime();
+							
+							response.setScrapeStartTime( now );
+							
+							response.setNextScrapeStartTime( now + 5*60*1000 );
+
+							response.setStatus( 
+									TRTrackerScraperResponse.ST_ONLINE,
+									MessageText.getString( "Scrape.status.cached" )); 
+						
+							responses.put( torrent.getHashWrapper(), response );
+							
+							scraper.scrapeReceived( response );
+						}
+					}
+				}
+				
+				return( response );
 				
 			}catch( TOTorrentException e ){
 				
@@ -136,20 +176,7 @@ TRTrackerDHTScraperImpl
 	scrape(
 		TRTrackerAnnouncer	tracker_client )
 	{
-		TOTorrent	torrent = tracker_client.getTorrent();
-		
-		if ( torrent != null ){
-
-			try{
-				return((TRTrackerScraperResponse)responses.get( torrent.getHashWrapper()));
-				
-			}catch( TOTorrentException e ){
-				
-				Debug.printStackTrace(e);
-			}
-		}
-		
-		return( null );	
+		return( scrape( tracker_client.getTorrent(), null, false ));
 	}
 	
 	public void
diff --git a/org/gudy/azureus2/core3/tracker/host/impl/TRHostConfigImpl.java b/org/gudy/azureus2/core3/tracker/host/impl/TRHostConfigImpl.java
index 2756f9e..995700e 100644
--- a/org/gudy/azureus2/core3/tracker/host/impl/TRHostConfigImpl.java
+++ b/org/gudy/azureus2/core3/tracker/host/impl/TRHostConfigImpl.java
@@ -53,6 +53,8 @@ TRHostConfigImpl
 	private Map			saved_stats				= new HashMap();
 	private List		saved_stats_to_delete	= new ArrayList();
 	
+	private boolean		config_exists = true;
+	
 	private AEMonitor this_mon 	= new AEMonitor( "TRHostConfig" );
 
 	protected
@@ -427,8 +429,21 @@ TRHostConfigImpl
 			   	try{
 			   		save_lock_mon.enter();
 			   		
-			   		FileUtil.writeResilientConfigFile( "tracker.config", map );
-				   	
+			   		if ( torrents.length == 0 ){
+			   			
+			   			if ( config_exists ){
+			   		
+			   				FileUtil.deleteResilientConfigFile( "tracker.config" );
+			   				
+			   				config_exists = false;
+			   			}
+			   		}else{
+			   		
+			   			config_exists = true;
+			   			
+			   			FileUtil.writeResilientConfigFile( "tracker.config", map );
+			   		}
+			   		
 					if ( 	COConfigurationManager.getBooleanParameter( "Tracker Log Enable") &&
 							stats_entries.size() > 0 ){
 				   		
diff --git a/org/gudy/azureus2/core3/tracker/host/impl/TRHostExternalTorrent.java b/org/gudy/azureus2/core3/tracker/host/impl/TRHostExternalTorrent.java
index 029b2d4..237732d 100644
--- a/org/gudy/azureus2/core3/tracker/host/impl/TRHostExternalTorrent.java
+++ b/org/gudy/azureus2/core3/tracker/host/impl/TRHostExternalTorrent.java
@@ -112,6 +112,12 @@ TRHostExternalTorrent
 		return( null );
 	}
 	
+ 	public void
+	setCreatedBy(
+		byte[]		cb )
+   	{
+   	}
+ 	
 	public boolean
 	isCreated()
 	{
diff --git a/org/gudy/azureus2/core3/tracker/server/impl/tcp/nonblocking/TRNonBlockingServer.java b/org/gudy/azureus2/core3/tracker/server/impl/tcp/nonblocking/TRNonBlockingServer.java
index 3a54b4a..0782442 100644
--- a/org/gudy/azureus2/core3/tracker/server/impl/tcp/nonblocking/TRNonBlockingServer.java
+++ b/org/gudy/azureus2/core3/tracker/server/impl/tcp/nonblocking/TRNonBlockingServer.java
@@ -82,6 +82,8 @@ TRNonBlockingServer
 
 	private VirtualServerChannelSelector accept_server;
 	
+	private boolean immediate_close;
+	
 	private volatile boolean	closed;
 	
 	public
@@ -211,6 +213,13 @@ TRNonBlockingServer
 		}
 	}
 	
+	public void
+	setImmediateClose(
+		boolean	immediate )
+	{
+		immediate_close = immediate;
+	}
+	
 	protected void
 	selectLoop(
       VirtualChannelSelector	selector )
@@ -426,7 +435,20 @@ TRNonBlockingServer
         		read_selector.cancel( processor.getSocketChannel() );
         		write_selector.cancel( processor.getSocketChannel() );
         	
-        		connections_to_close.add( processor );
+        		if ( immediate_close ){
+
+        			try{
+        				processor.closed();
+
+        				processor.getSocketChannel().close();
+        				
+        			}catch( Throwable e ){
+        				
+        			}
+        		}else{
+        			
+        			connections_to_close.add( processor );
+        		}
         	}
         	
         }finally{
diff --git a/org/gudy/azureus2/core3/tracker/util/TRTrackerUtils.java b/org/gudy/azureus2/core3/tracker/util/TRTrackerUtils.java
index aa1ec35..e95dd2b 100644
--- a/org/gudy/azureus2/core3/tracker/util/TRTrackerUtils.java
+++ b/org/gudy/azureus2/core3/tracker/util/TRTrackerUtils.java
@@ -57,7 +57,8 @@ TRTrackerUtils
 	private static int[]		BLACKLISTED_PORTS	= 
 		{ 81 };
 
-	private static String		tracker_ip;
+	private static String			tracker_ip;
+	private static Set<String>		tracker_ip_aliases;
 	
 	private static Map			override_map;
 	
@@ -316,9 +317,31 @@ TRTrackerUtils
 	static void
 	readConfig()
 	{
-		tracker_ip 		= COConfigurationManager.getStringParameter("Tracker IP", "");
+		tracker_ip 	= COConfigurationManager.getStringParameter("Tracker IP", "");
 	
-		tracker_ip = UrlUtils.expandIPV6Host( tracker_ip );
+		tracker_ip 	= UrlUtils.expandIPV6Host( tracker_ip );
+		
+		String	aliases = COConfigurationManager.getStringParameter("Tracker IP Aliases", "");
+		
+		if ( aliases.length() > 0 ){
+			
+			tracker_ip_aliases = new HashSet<String>();
+			
+			String[] bits = aliases.split(",");
+			
+			for (String b: bits ){
+				
+				b = b.trim();
+				
+				if ( b.length() > 0 ){
+					
+					tracker_ip_aliases.add( b );
+				}
+			}
+		}else{
+			
+			tracker_ip_aliases = null;
+		}
 		
 		String override_ips		= COConfigurationManager.getStringParameter("Override Ip", "");
 		
@@ -354,8 +377,23 @@ TRTrackerUtils
 	isHosting(
 		URL		url_in )
 	{
-		return( tracker_ip.length() > 0  &&
-				UrlUtils.expandIPV6Host(url_in.getHost()).equalsIgnoreCase( tracker_ip ));
+		if ( tracker_ip.length() > 0  ){
+			
+			String host = UrlUtils.expandIPV6Host(url_in.getHost());
+			
+			boolean	result = host.equalsIgnoreCase( tracker_ip );
+			
+			if ( !result && tracker_ip_aliases != null ){
+			
+				result = tracker_ip_aliases.contains( host );
+			}
+		
+			return( result );
+			
+		}else{
+			
+			return( false );
+		}
 	}
 	
 	public static String
diff --git a/org/gudy/azureus2/core3/util/AEDiagnostics.java b/org/gudy/azureus2/core3/util/AEDiagnostics.java
index 0bb8458..b398dd0 100644
--- a/org/gudy/azureus2/core3/util/AEDiagnostics.java
+++ b/org/gudy/azureus2/core3/util/AEDiagnostics.java
@@ -23,6 +23,7 @@
 package org.gudy.azureus2.core3.util;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.platform.PlatformManager;
@@ -116,6 +117,7 @@ AEDiagnostics
 	
 	private static Map<String,AEDiagnosticsLogger>		loggers	= new HashMap<String, AEDiagnosticsLogger>();
 	
+	protected static boolean	logging_enabled;
 	protected static boolean	loggers_enabled;
 	
 	private static List		evidence_generators	= new ArrayList();
@@ -151,8 +153,23 @@ AEDiagnostics
 			
 			debug_save_dir	= new File( debug_dir, "save" );
 			
-			loggers_enabled = COConfigurationManager.getBooleanParameter( "Logger.DebugFiles.Enabled");
-
+			COConfigurationManager.addAndFireParameterListeners(
+				new String[]{
+					"Logger.Enabled",
+					"Logger.DebugFiles.Enabled",	
+				},
+				new ParameterListener()
+				{
+					public void 
+					parameterChanged(
+						String parameterName) 
+					{			
+						logging_enabled = COConfigurationManager.getBooleanParameter( "Logger.Enabled" );
+						
+						loggers_enabled = logging_enabled && COConfigurationManager.getBooleanParameter( "Logger.DebugFiles.Enabled");
+					}
+				});
+			
 			boolean	was_tidy	= COConfigurationManager.getBooleanParameter( CONFIG_KEY );
 			
 			new AEThread2( "asyncify", true )
@@ -172,9 +189,7 @@ AEDiagnostics
 			if ( debug_dir.exists()){
 				
 				long	now = SystemTime.getCurrentTime();
-				
-				debug_save_dir.mkdir();
-				
+								
 				File[] files = debug_dir.listFiles();
 				
 				if ( files != null ){
@@ -192,6 +207,11 @@ AEDiagnostics
 						
 						if ( !was_tidy ){
 				
+							if ( !file_copied ){
+								
+								debug_save_dir.mkdir();
+							}
+							
 							file_copied	= true;
 							
 							FileUtil.copyFile( file, new File( debug_save_dir, now + "_" + file.getName()));
diff --git a/org/gudy/azureus2/core3/util/AEDiagnosticsLogger.java b/org/gudy/azureus2/core3/util/AEDiagnosticsLogger.java
index c2f6fee..d416904 100644
--- a/org/gudy/azureus2/core3/util/AEDiagnosticsLogger.java
+++ b/org/gudy/azureus2/core3/util/AEDiagnosticsLogger.java
@@ -47,6 +47,7 @@ AEDiagnosticsLogger
 	private int				max_size;
 	private File			debug_dir;
 	private boolean			timestamp_enable				= true;
+	private boolean			force;
 	
 	private boolean			first_file				= true;
 	private boolean			first_write			 	= true;
@@ -104,6 +105,12 @@ AEDiagnosticsLogger
 		}
 	}
 	
+	protected void
+	setForced()
+	{
+		force = true;
+	}
+	
 	protected String
 	getName()
 	{
@@ -237,7 +244,10 @@ AEDiagnosticsLogger
 	{
 		if ( !AEDiagnostics.loggers_enabled ){
 			
-			return;
+			if ( !force ){
+			
+				return;
+			}
 		}
 		
 		StringBuilder str = new StringBuilder( _str.length() + 20 );
diff --git a/org/gudy/azureus2/core3/util/AERunnableBoolean.java b/org/gudy/azureus2/core3/util/AERunnableBoolean.java
index e92bbe7..1ac5c8e 100644
--- a/org/gudy/azureus2/core3/util/AERunnableBoolean.java
+++ b/org/gudy/azureus2/core3/util/AERunnableBoolean.java
@@ -48,7 +48,7 @@ public abstract class AERunnableBoolean
 			//System.out.println(this + "]" + id + " sem=" + sem);
 			if (sem != null) {
 				//System.out.println(this + "]" + id + " sem Release");
-				sem.release();
+				sem.releaseForever();
 			}
 		}
 	}
diff --git a/org/gudy/azureus2/core3/util/AEThread2.java b/org/gudy/azureus2/core3/util/AEThread2.java
index acb8017..cbc7bec 100644
--- a/org/gudy/azureus2/core3/util/AEThread2.java
+++ b/org/gudy/azureus2/core3/util/AEThread2.java
@@ -33,8 +33,8 @@ AEThread2
 {
 	public static final boolean TRACE_TIMES = false;
 	
-	private static final int MIN_RETAINED	= 2;
-	private static final int MAX_RETAINED	= 16;
+	private static final int MIN_RETAINED	= Math.max(Runtime.getRuntime().availableProcessors(),2);
+	private static final int MAX_RETAINED	= Math.max(MIN_RETAINED*4, 16);
 	
 	private static final int THREAD_TIMEOUT_CHECK_PERIOD	= 10*1000;
 	private static final int THREAD_TIMEOUT					= 60*1000;
diff --git a/org/gudy/azureus2/core3/util/AddressUtils.java b/org/gudy/azureus2/core3/util/AddressUtils.java
index 71bbb8d..7163c09 100644
--- a/org/gudy/azureus2/core3/util/AddressUtils.java
+++ b/org/gudy/azureus2/core3/util/AddressUtils.java
@@ -22,10 +22,14 @@
 
 package org.gudy.azureus2.core3.util;
 
-import java.util.*;
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.instancemanager.AZInstance;
@@ -303,4 +307,59 @@ AddressUtils
 		return is_lan_local;
 	}
 	
+	/**
+	 * checks if the provided address is a global-scope ipv6 unicast address
+	 */
+	public static boolean isGlobalAddressV6(InetAddress addr) {
+		return addr instanceof Inet6Address && !addr.isAnyLocalAddress() && !addr.isLinkLocalAddress() && !addr.isLoopbackAddress() && !addr.isMulticastAddress() && !addr.isSiteLocalAddress() && !((Inet6Address)addr).isIPv4CompatibleAddress();
+	}
+	
+	public static boolean isTeredo(InetAddress addr)
+	{
+		if(!(addr instanceof Inet6Address))
+			return false;
+		byte[] bytes = addr.getAddress();
+		// check for the 2001:0000::/32 prefix, i.e. teredo
+		return bytes[0] == 0x20 && bytes[1] == 0x01 && bytes[2] == 0x00 && bytes[3] == 0x00;
+	}
+	
+	public static boolean is6to4(InetAddress addr)
+	{
+		if(!(addr instanceof Inet6Address))
+			return false;
+		byte[] bytes = addr.getAddress();
+		// check for the 2002::/16 prefix, i.e. 6to4
+		return bytes[0] == 0x20 && bytes[1] == 0x02;
+	}
+	
+	/**
+	 * picks 1 global-scoped address out of a list based on the heuristic
+	 * "true" ipv6/tunnel broker > 6to4 > teredo
+	 * 
+	 * @return null if no proper v6 address is found, best one otherwise
+	 */
+	public static InetAddress pickBestGlobalV6Address(List<InetAddress> addrs)
+	{
+		InetAddress bestPick = null;
+		int currentRanking = 0;
+		for(InetAddress addr : addrs)
+		{
+			if(!isGlobalAddressV6(addr))
+				continue;
+			int ranking = 3;
+			if(isTeredo(addr))
+				ranking = 1;
+			else if(is6to4(addr))
+				ranking = 2;
+			
+			if(ranking > currentRanking)
+			{
+				bestPick = addr;
+				currentRanking = ranking;
+			}
+		}
+		
+		return bestPick;
+	}
+	
 }
diff --git a/org/gudy/azureus2/core3/util/Average.java b/org/gudy/azureus2/core3/util/Average.java
index a7ed167..d2ca899 100644
--- a/org/gudy/azureus2/core3/util/Average.java
+++ b/org/gudy/azureus2/core3/util/Average.java
@@ -263,6 +263,6 @@ public class Average {
   protected long
   getEffectiveTime()
   {
-	  return( SystemTime.getMonotonousTime());
+	  return( SystemTime.getSteppedMonotonousTime());
   }
 }
diff --git a/org/gudy/azureus2/core3/util/BDecoder.java b/org/gudy/azureus2/core3/util/BDecoder.java
index 2a43967..aee5caf 100644
--- a/org/gudy/azureus2/core3/util/BDecoder.java
+++ b/org/gudy/azureus2/core3/util/BDecoder.java
@@ -150,6 +150,9 @@ public class BDecoder
 
 		return((Map)res );
 	}
+	
+	// reuseable buffer for keys, recursion is not an issue as this is only a temporary buffer that gets converted into a string immediately
+	private ByteBuffer keyBytesBuffer = ByteBuffer.allocate(32);
 
 	private Object 
 	decodeInputStream(
@@ -183,41 +186,53 @@ public class BDecoder
 			try{
 					//get the key   
 				
-				byte[] tempByteArray = null;
-
-				while ((tempByteArray = (byte[]) decodeInputStream(dbis, nesting+1,internKeys)) != null) {
+				while (true) {
+					
+					dbis.mark(Integer.MAX_VALUE);
 
-					if ( tempByteArray.length > MAX_MAP_KEY_SIZE ){
-						
-						String msg = "dictionary key is too large, max=" + MAX_MAP_KEY_SIZE + ": value=" + new String( tempByteArray, 0, 128 );
-						
-						System.err.println( msg );
-						
-						throw( new IOException( msg ));
-					}
-						//decode some more
+					tempByte = dbis.read();
+					if(tempByte == 'e' || tempByte == -1)
+						break; // end of map
 
-					Object value = decodeInputStream(dbis,nesting+1,internKeys);
+					dbis.reset();
 					
-						// value interning is too CPU-intensive, let's skip that for now
-						//if(value instanceof byte[] && ((byte[])value).length < 17)
-						//value = StringInterner.internBytes((byte[])value);
+					// decode key strings manually so we can reuse the bytebuffer
 
+					int keyLength = (int)getNumberFromStream(dbis, ':');
 
-						// keys often repeat a lot - intern to save space
+					ByteBuffer keyBytes;
+					if(keyLength < keyBytesBuffer.capacity())
+					{
+						keyBytes = keyBytesBuffer;
+						keyBytes.position(0).limit(keyLength);
+					} else {
+						keyBytes = keyBytesBuffer = ByteBuffer.allocate(keyLength);
+					}
 					
-					String	key = null;//StringInterner.intern( tempByteArray );
-
-					if ( key == null ){
+					getByteArrayFromStream(dbis, keyLength, keyBytes.array());						
 
-						CharBuffer	cb = Constants.BYTE_CHARSET.decode(ByteBuffer.wrap(tempByteArray));
+					if ( keyLength > MAX_MAP_KEY_SIZE ){
+						String msg = "dictionary key is too large, max=" + MAX_MAP_KEY_SIZE + ": value=" + new String( keyBytes.array(), 0, 128 );
+						System.err.println( msg );
+						throw( new IOException( msg ));
+					}
+					
+					CharBuffer	cb = Constants.BYTE_CHARSET.decode(keyBytes);
+					String key = new String(cb.array(),0,cb.limit());
+					
+					// keys often repeat a lot - intern to save space
+					if (internKeys)
+						key = StringInterner.intern( key );
+					
+					
 
-						key = new String(cb.array(),0,cb.limit());
+					//decode value
 
-						if (internKeys) {
-							key = StringInterner.intern( key );
-						}
-					}
+					Object value = decodeInputStream(dbis,nesting+1,internKeys);
+					
+					// value interning is too CPU-intensive, let's skip that for now
+					/*if(value instanceof byte[] && ((byte[])value).length < 17)
+					value = StringInterner.internBytes((byte[])value);*/
 
 					if ( TRACE ){
 						System.out.println( key + "->" + value + ";" );
@@ -318,7 +333,7 @@ public class BDecoder
 			return null;
 
 		case 'i' :
-			return new Long(getNumberFromStream(dbis, 'e'));
+			return Long.valueOf(getNumberFromStream(dbis, 'e'));
 
 		case '0' :
 		case '1' :
@@ -419,10 +434,31 @@ public class BDecoder
 			return(0);
 		}
 
-		return( parseLong( numberChars, 0, pos ));
+		try{
+			return( parseLong( numberChars, 0, pos ));
+			
+		}catch( NumberFormatException e ){
+			
+			String temp = new String( numberChars, 0, pos );
+			
+			try{
+				double d = Double.parseDouble( temp );
+				
+				long l = (long)d;
+				
+				Debug.out( "Invalid number '" + temp + "' - decoding as " + l + " and attempting recovery" );
+					
+				return( l );
+				
+			}catch( Throwable f ){
+			}
+			
+			throw( e );
+		}
 	}
 
 	// This is similar to Long.parseLong(String) source
+	// It is also used in projects external to azureus2/azureus3 hence it is public
 	public static long
 	parseLong(
 		char[]	chars,
@@ -604,21 +640,25 @@ public class BDecoder
 
 			throw( new IOException( "Byte array length too large (" + length + ")"));
 		}
-
+		
 		byte[] tempArray = new byte[length];
+		
+		getByteArrayFromStream(dbis, length, tempArray);		
+		
+		return tempArray; 
+	}
+
+	private void getByteArrayFromStream(InputStream dbis, int length, byte[] targetArray) throws IOException {
+
 		int count = 0;
 		int len = 0;
 		//get the string
-		while (count != length && (len = dbis.read(tempArray, count, length - count)) > 0) {
+		while (count != length && (len = dbis.read(targetArray, count, length - count)) > 0)
 			count += len;
-		}
 
-		if ( count != tempArray.length ){
-			throw( new IOException( "BDecoder::getByteArrayFromStream: truncated"));
-		}
-
-		return tempArray;
-	}
+		if (count != length)
+			throw (new IOException("BDecoder::getByteArrayFromStream: truncated"));
+	}	
 
 	public void
 	setRecoveryMode(
diff --git a/org/gudy/azureus2/core3/util/BEncodableObject.java b/org/gudy/azureus2/core3/util/BEncodableObject.java
new file mode 100644
index 0000000..4637733
--- /dev/null
+++ b/org/gudy/azureus2/core3/util/BEncodableObject.java
@@ -0,0 +1,36 @@
+/*
+ * Created on Oct 24, 2009 10:21:17 PM
+ * Copyright (C) 2009 Aelitis, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * AELITIS, SAS au capital de 46,603.30 euros
+ * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
+ */
+package org.gudy.azureus2.core3.util;
+
+
+/**
+ * Classes that implement this interface can be sent to a bencode
+ * 
+ * @author TuxPaper
+ * @created Oct 24, 2009
+ *
+ */
+public interface BEncodableObject
+{
+	/**
+	 * @return Must return an object that is bencodable
+	 */
+	public Object toBencodeObject();
+}
diff --git a/org/gudy/azureus2/core3/util/BEncoder.java b/org/gudy/azureus2/core3/util/BEncoder.java
index 80e347e..b5e6a7b 100644
--- a/org/gudy/azureus2/core3/util/BEncoder.java
+++ b/org/gudy/azureus2/core3/util/BEncoder.java
@@ -87,6 +87,10 @@ BEncoder
     	throws IOException
 	{
     	
+        if (object instanceof BEncodableObject) {
+            object = ((BEncodableObject)object).toBencodeObject();
+        }
+
         if ( object instanceof String || object instanceof Float){
         	
             String tempString = (object instanceof String) ? (String)object : String.valueOf((Float)object);
@@ -478,7 +482,7 @@ BEncoder
     }
     
     public static boolean isEncodable(Object toCheck) {
-		if (toCheck instanceof Integer || toCheck instanceof Long || toCheck instanceof Boolean || toCheck instanceof Float || toCheck instanceof byte[] || toCheck instanceof String)
+		if (toCheck instanceof Integer || toCheck instanceof Long || toCheck instanceof Boolean || toCheck instanceof Float || toCheck instanceof byte[] || toCheck instanceof String || toCheck instanceof BEncodableObject)
 			return true;
 		if (toCheck instanceof Map)
 		{
diff --git a/org/gudy/azureus2/core3/util/ByteFormatter.java b/org/gudy/azureus2/core3/util/ByteFormatter.java
index 28b8662..180e4dc 100644
--- a/org/gudy/azureus2/core3/util/ByteFormatter.java
+++ b/org/gudy/azureus2/core3/util/ByteFormatter.java
@@ -178,6 +178,11 @@ public class ByteFormatter
     return out;
   }
 
+  	/**
+  	 * Note this has a truncation limit at 1024 chars....
+  	 * @param bytes
+  	 * @return
+  	 */
   public static String
   encodeString(
   	byte[]		bytes )
@@ -186,6 +191,13 @@ public class ByteFormatter
   }
   
   public static String
+  encodeStringFully(
+  	byte[]		bytes )
+  {
+  	return( nicePrint( bytes, true,  Integer.MAX_VALUE ));
+  }
+  
+  public static String
   encodeString(
   	byte[]		bytes,
   	int			offset,
diff --git a/org/gudy/azureus2/core3/util/Constants.java b/org/gudy/azureus2/core3/util/Constants.java
index 6e2237e..4ba8552 100644
--- a/org/gudy/azureus2/core3/util/Constants.java
+++ b/org/gudy/azureus2/core3/util/Constants.java
@@ -35,23 +35,24 @@ Constants
 {
   public static final String EMPTY_STRING = "";
   public static final String SF_WEB_SITE			= "http://azureus.sourceforge.net/";
-  //public static final String AELITIS_WEB_SITE   	= "http://azureus.aelitis.com/";  
-  //public static final String GETAZUREUS_WEB_SITE	= "http://www.getazureus.com/";
-  
-  public static final String AELITIS_TORRENTS		= "http://torrents.aelitis.com:88/torrents/";
-  public static final String AELITIS_FILES			= "http://torrents.aelitis.com:88/files/";
+ 
+  public static final String AELITIS_TORRENTS		= "http://torrent.vuze.com:88/torrents/";
+  public static final String AELITIS_FILES			= "http://torrent.vuze.com:88/files/";
   public static final String AZUREUS_WIKI 			= "http://wiki.vuze.com/index.php/";
   
-  public static final String  VERSION_SERVER_V4 	= "version.azureusplatform.com";
-  public static final String  VERSION_SERVER_V6 	= "version6.azureusplatform.com";
+  public static final String  VERSION_SERVER_V4 	= "version.vuze.com";
+  public static final String  VERSION_SERVER_V6 	= "version6.vuze.com";
 
-  public static final String DHT_SEED_ADDRESS_V4	= "dht.aelitis.com";
-  public static final String DHT_SEED_ADDRESS_V6	= "dht6.azureusplatform.com";
+  public static final String DHT_SEED_ADDRESS_V4	= "dht.vuze.com";
+  public static final String DHT_SEED_ADDRESS_V6	= "dht6.vuze.com";
   
-  public static final String NAT_TEST_SERVER		= "nettest.azureusplatform.com";
-  public static final String NAT_TEST_SERVER_HTTP	= "http://nettest.azureusplatform.com/";
+  public static final String NAT_TEST_SERVER		= "nettest.vuze.com";
+  public static final String NAT_TEST_SERVER_HTTP	= "http://nettest.vuze.com/";
    
-  public static final String SPEED_TEST_SERVER		= "speed.azureusplatform.com";
+  public static final String SPEED_TEST_SERVER		= "speedtest.vuze.com";
+  
+  public static final String PAIRING_URL			= "http://pair.vuze.com/pairing";
+
   
   public static final String[] AZUREUS_DOMAINS = { "azureusplatform.com", "azureus.com", "aelitis.com", "vuze.com" };
   
@@ -84,9 +85,12 @@ Constants
   
   public static String APP_NAME = "Vuze";
   public static final String AZUREUS_NAME	  = "Azureus";
-  public static final String AZUREUS_VERSION  = "4.2.0.8";  //4.2.0.9_CVS
-  public static final byte[] VERSION_ID       = ("-" + "AZ" + "4208" + "-").getBytes();  //MUST be 8 chars long!
+  public static final String AZUREUS_VERSION  = "4.3.0.0";  //4.3.0.1_CVS
+  public static final byte[] VERSION_ID       = ("-" + "AZ" + "4300" + "-").getBytes();  //MUST be 8 chars long!
+
+  private static final boolean FORCE_NON_CVS = System.getProperty( "az.force.noncvs", "0" ).equals( "1" );
   
+  public static final boolean IS_CVS_VERSION = isCVSVersion( AZUREUS_VERSION ) && !FORCE_NON_CVS;
   
   public static final String  OSName = System.getProperty("os.name");
   
@@ -130,6 +134,39 @@ Constants
 	  }
   }
   
+  public static final boolean isOSX_10_5_OrHigher;
+  public static final boolean isOSX_10_6_OrHigher;
+  
+  static{
+	  if ( isOSX ){
+		 
+		  int	first_digit 	= 0;
+		  int	second_digit	= 0;
+		  
+		  try{
+			  String os_version = System.getProperty( "os.version" );
+
+			  String[] bits = os_version.split( "\\." );
+			
+			  first_digit = Integer.parseInt( bits[0] );
+			  
+			  if ( bits.length > 1 ){
+			  
+				  second_digit = Integer.parseInt( bits[1] );
+			  }
+		  }catch( Throwable e ){
+			  
+		  }
+		  
+		  isOSX_10_5_OrHigher = first_digit > 10 || ( first_digit == 10 && second_digit >= 5 );
+		  isOSX_10_6_OrHigher = first_digit > 10 || ( first_digit == 10 && second_digit >= 6 );
+		  
+	  }else{
+		  
+		  isOSX_10_5_OrHigher = false;
+		  isOSX_10_6_OrHigher = false;
+	  }
+  }
   
   public static final String	JAVA_VERSION = System.getProperty("java.version");
   
@@ -168,7 +205,7 @@ Constants
   public static boolean
   isCVSVersion()
   {
-  	return( isCVSVersion( AZUREUS_VERSION )); 
+  	return IS_CVS_VERSION; 
   }
   
   public static boolean
diff --git a/org/gudy/azureus2/core3/util/Debug.java b/org/gudy/azureus2/core3/util/Debug.java
index 54a1eef..6c57078 100644
--- a/org/gudy/azureus2/core3/util/Debug.java
+++ b/org/gudy/azureus2/core3/util/Debug.java
@@ -32,6 +32,9 @@ public class Debug {
   
 	private static AEDiagnosticsLogger	diag_logger	= AEDiagnostics.getLogger( "debug" );
 
+	static{
+		diag_logger.setForced();
+	}
   
   /**
    * Prints out the given debug message to System.out,
diff --git a/org/gudy/azureus2/core3/util/DisplayFormatters.java b/org/gudy/azureus2/core3/util/DisplayFormatters.java
index 827dd6c..2a535a2 100644
--- a/org/gudy/azureus2/core3/util/DisplayFormatters.java
+++ b/org/gudy/azureus2/core3/util/DisplayFormatters.java
@@ -75,6 +75,7 @@ DisplayFormatters
 	private static String		per_sec;
 	
 	private static boolean use_si_units;
+	private static boolean force_si_values;
 	private static boolean use_units_rate_bits;
 	private static boolean not_use_GB_TB;
 
@@ -85,53 +86,30 @@ DisplayFormatters
 		private static char decimalSeparator;
     
 	static{
-		use_si_units = COConfigurationManager.getBooleanParameter("config.style.useSIUnits");
-
-		COConfigurationManager.addParameterListener( "config.style.useSIUnits",
-				new ParameterListener()
-				{
-					public void
-					parameterChanged(
-						String	value )
-					{
-						use_si_units = COConfigurationManager.getBooleanParameter("config.style.useSIUnits");
-
-						setUnits();
-					}
-				});
-
-		use_units_rate_bits = COConfigurationManager.getBooleanParameter("config.style.useUnitsRateBits");
-
-		COConfigurationManager.addParameterListener( "config.style.useUnitsRateBits",
+		COConfigurationManager.addAndFireParameterListeners( 
+				new String[]{
+					"config.style.useSIUnits",
+					"config.style.forceSIValues",
+					"config.style.useUnitsRateBits",
+					"config.style.doNotUseGB",
+				},
 				new ParameterListener()
 				{
 					public void
 					parameterChanged(
-						String	value )
+						String	x )
 					{
+						use_si_units 		= COConfigurationManager.getBooleanParameter("config.style.useSIUnits");
+						force_si_values 		= COConfigurationManager.getBooleanParameter("config.style.forceSIValues");
 						use_units_rate_bits = COConfigurationManager.getBooleanParameter("config.style.useUnitsRateBits");
+			            not_use_GB_TB 		= COConfigurationManager.getBooleanParameter("config.style.doNotUseGB");
+			            
+			            unitsStopAt = (not_use_GB_TB) ? UNIT_MB : UNIT_TB;
 
 						setUnits();
 					}
 				});
 
-	    not_use_GB_TB = COConfigurationManager.getBooleanParameter("config.style.doNotUseGB");
-	    unitsStopAt = (not_use_GB_TB) ? UNIT_MB : UNIT_TB;
-	
-	    COConfigurationManager.addParameterListener( "config.style.doNotUseGB",
-	        new ParameterListener()
-	        {
-	          public void
-	          parameterChanged(
-	            String  value )
-	          {
-	            not_use_GB_TB = COConfigurationManager.getBooleanParameter("config.style.doNotUseGB");
-	            unitsStopAt = (not_use_GB_TB) ? UNIT_MB : UNIT_TB;
-	
-							setUnits();
-	          }
-	        });
-
     	COConfigurationManager.addListener(
     		new COConfigurationListener()
     		{
@@ -146,7 +124,10 @@ DisplayFormatters
     		});
 		
 		COConfigurationManager.addAndFireParameterListeners( 
-				new String[]{ "config.style.dataStatsOnly", "config.style.separateProtDataStats" },
+				new String[]{ 
+						"config.style.dataStatsOnly", 
+						"config.style.separateProtDataStats" 
+				},
 				new ParameterListener()
 				{
 					public void
@@ -410,9 +391,11 @@ DisplayFormatters
 
 	  	int unitIndex = UNIT_B;
 	  	
-	  	while (dbl >= 1024 && unitIndex < unitsStopAt){ 
+        long	div = force_si_values?1024:(use_si_units?1024:1000);
+        
+	  	while (dbl >= div && unitIndex < unitsStopAt){ 
 	  	
-		  dbl /= 1024L;
+		  dbl /= div;
 		  unitIndex++;
 		}
 	  	
@@ -582,9 +565,11 @@ DisplayFormatters
 
         int unitIndex = UNIT_B;
 
-        while (dbl >= 1024 && unitIndex < unitsStopAt){
+        long	div = force_si_values?1024:(use_si_units?1024:1000);
+        
+        while (dbl >= div && unitIndex < unitsStopAt){
 
-          dbl /= 1024L;
+          dbl /= div;
           unitIndex++;
         }
 
diff --git a/org/gudy/azureus2/core3/util/FileUtil.java b/org/gudy/azureus2/core3/util/FileUtil.java
index a14a93a..902701f 100644
--- a/org/gudy/azureus2/core3/util/FileUtil.java
+++ b/org/gudy/azureus2/core3/util/FileUtil.java
@@ -169,7 +169,33 @@ public class FileUtil {
     
     return( true );
   }
-  
+
+  public static boolean recursiveDeleteNoCheck(File f) {
+    try {
+      if (f.isDirectory()) {
+        File[] files = f.listFiles();
+        for (int i = 0; i < files.length; i++) {
+          if ( !recursiveDeleteNoCheck(files[i])){
+        	  
+        	  return( false );
+          }
+        }
+        if ( !f.delete()){
+        	
+        	return( false );
+        }
+      }
+      else {
+        if ( !f.delete()){
+        	
+        	return( false );
+        }
+      }
+    } catch (Exception ignore) {/*ignore*/}
+    
+    return( true );
+  }  
+ 
   public static long
   getFileOrDirectorySize(
   	File		file )
@@ -399,6 +425,15 @@ public class FileUtil {
 	  writeResilientFile( file.getParentFile(), file.getName(), data, false );
   }
   
+  public static boolean
+  writeResilientFileWithResult(
+    File		parent_dir,
+  	String		file_name,
+	Map			data )
+  {
+	  return( writeResilientFile( parent_dir, file_name, data ));
+  }
+  
   public static void
   writeResilientFile(
     File		parent_dir,
@@ -432,63 +467,102 @@ public class FileUtil {
   
   	// synchronise it to prevent concurrent attempts to write the same file
   
-  private static void
+  private static boolean
   writeResilientFile(
 	File		parent_dir,
   	String		file_name,
 	Map			data )
   {
-  	try{
-  		class_mon.enter();
-  	
-	  	try{
-	  		getReservedFileHandles();
-	      File temp = new File(  parent_dir, file_name + ".saving");
-		    BufferedOutputStream	baos = null;
-		    
-		    try{
-		    	byte[] encoded_data = BEncoder.encode(data);
-		    	FileOutputStream tempOS = new FileOutputStream( temp, false );
-		    	baos = new BufferedOutputStream( tempOS, 8192 );
-		    	baos.write( encoded_data );
-		    	baos.flush();
-		    	tempOS.getFD().sync();
-	        baos.close();
-	        baos = null;
-	           
-	        //only use newly saved file if it got this far, i.e. it saved successfully
-	        if ( temp.length() > 1L ) {
-	        	File file = new File( parent_dir, file_name );
-	        	if ( file.exists() ){
-	        		file.delete();
-	        	}
-	        	temp.renameTo( file );
-	        }
-	
-		    }catch (Exception e) {
-		    	Logger.log(new LogAlert(LogAlert.UNREPEATABLE, "Save of '"
-							+ file_name + "' fails", e));
-		    	
-		    }finally{
-		    	
-		    	try {
-		    		if (baos != null){
-		    			
-		    			baos.close();
-		    		}
-		    	}catch( Exception e){
-		    		Logger.log(new LogAlert(LogAlert.UNREPEATABLE, "Save of '"
-								+ file_name + "' fails", e)); 
-		    	}
-		    }
-	  	}finally{
-	  		
-	  		releaseReservedFileHandles();
-	  	}
-  	}finally{
-  		
-  		class_mon.exit();
-  	}
+	  try{
+		  class_mon.enter();
+
+		  try{
+			  getReservedFileHandles();
+			  File temp = new File(  parent_dir, file_name + ".saving");
+			  BufferedOutputStream	baos = null;
+
+			  try{
+				  byte[] encoded_data = BEncoder.encode(data);
+				  FileOutputStream tempOS = new FileOutputStream( temp, false );
+				  baos = new BufferedOutputStream( tempOS, 8192 );
+				  baos.write( encoded_data );
+				  baos.flush();
+				  
+				  	// thinking about removing this - just do so for CVS for the moment
+				  
+				  if ( !Constants.isCVSVersion()){
+					  
+					  tempOS.getFD().sync();
+				  }
+				  
+				  baos.close();
+				  baos = null;
+
+				  	//only use newly saved file if it got this far, i.e. it saved successfully
+				  
+				  if ( temp.length() > 1L ){
+					  
+					  File file = new File( parent_dir, file_name );
+					  
+					  if ( file.exists()){
+						  
+						  if ( !file.delete()){
+							  
+							  Logger.log(
+								 new LogAlert(
+										 LogAlert.UNREPEATABLE, 
+										 LogAlert.AT_ERROR,
+										 "Save of '" + file_name + "' fails - couldn't delete " + file.getAbsolutePath()));
+ 
+						  }
+					  }
+					  
+					  if ( temp.renameTo( file )){
+						  
+						  return( true );
+						  
+					  }else{
+						  
+						  Logger.log(
+							 new LogAlert(
+									 LogAlert.UNREPEATABLE, 
+									 LogAlert.AT_ERROR,
+									 "Save of '" + file_name + "' fails - couldn't rename " + temp.getAbsolutePath() + " to " + file.getAbsolutePath()));
+
+					  }
+				  }
+					  
+				  return( false );
+
+			  }catch( Throwable e ){
+				  
+				  Logger.log(new LogAlert(LogAlert.UNREPEATABLE, "Save of '"
+						  + file_name + "' fails", e));
+
+				  return( false );
+				  
+			  }finally{
+
+				  try{
+					  if (baos != null){
+
+						  baos.close();
+					  }
+				  }catch( Exception e){
+					  Logger.log(new LogAlert(LogAlert.UNREPEATABLE, "Save of '"
+							  + file_name + "' fails", e)); 
+					  
+					  return( false );
+				  }
+			  }
+		  }finally{
+
+			  releaseReservedFileHandles();
+		  }
+	  }finally{
+
+		  class_mon.exit();
+	  }
   }
   
   	public static boolean
diff --git a/org/gudy/azureus2/core3/util/ListenerManager.java b/org/gudy/azureus2/core3/util/ListenerManager.java
index 59e7f71..e3ffc15 100644
--- a/org/gudy/azureus2/core3/util/ListenerManager.java
+++ b/org/gudy/azureus2/core3/util/ListenerManager.java
@@ -34,7 +34,9 @@ package org.gudy.azureus2.core3.util;
  */
 
 import java.lang.reflect.Method;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
 
 import org.gudy.azureus2.core3.logging.LogEvent;
 import org.gudy.azureus2.core3.logging.LogIDs;
@@ -71,7 +73,7 @@ ListenerManager<T>
 	protected boolean	async;
 	protected AEThread2	async_thread;
 	
-	protected List<T>			listeners		= new ArrayList<T>();
+	protected List<T>			listeners		= new ArrayList<T>(0);
 	
 	protected List<Object[]>	dispatch_queue;
 	protected AESemaphore		dispatch_sem;
diff --git a/org/gudy/azureus2/core3/util/StringInterner.java b/org/gudy/azureus2/core3/util/StringInterner.java
index 8038c04..5bb2df9 100644
--- a/org/gudy/azureus2/core3/util/StringInterner.java
+++ b/org/gudy/azureus2/core3/util/StringInterner.java
@@ -1,4 +1,5 @@
 /*
+
  * Created on Jun 8, 2007
  * Created by Paul Gardner
  * Copyright (C) 2007 Aelitis, All Rights Reserved.
@@ -24,15 +25,18 @@
 package org.gudy.azureus2.core3.util;
 
 import java.io.File;
-import java.lang.ref.*;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
 import java.net.URL;
 import java.util.*;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import com.aelitis.azureus.core.util.HashCodeUtils;
 
 
 public class 
-StringInterner 
+StringInterner
 {
 	private static final int SCHEDULED_CLEANUP_INTERVAL = 60*1000;
 	
@@ -48,6 +52,7 @@ StringInterner
 	
 	private static LightHashSet managedInterningSet = new LightHashSet(800);
 	private static LightHashSet unmanagedInterningSet = new LightHashSet();
+	private static ReadWriteLock managedSetLock = new ReentrantReadWriteLock();
 	
 	private final static ReferenceQueue managedRefQueue = new ReferenceQueue();
 	private final static ReferenceQueue unmanagedRefQueue = new ReferenceQueue();
@@ -92,7 +97,14 @@ StringInterner
 			{
 				SimpleTimer.addPeriodicEvent("StringInterner:cleaner", SCHEDULED_CLEANUP_INTERVAL, new TimerEventPerformer() {
 					public void perform(TimerEvent event) {
-						sanitize(true);
+						managedSetLock.writeLock().lock();
+						try {
+							sanitize(true);
+						} finally {
+							managedSetLock.writeLock().unlock();
+						}
+						
+						
 						sanitizeLight();
 					}
 				});
@@ -114,116 +126,150 @@ StringInterner
 		return( res );
 	}
 	
-	public static String intern(String toIntern) {
-		
+	/**
+	 * A generic interning facilty for heavyweight or frequently duplicated
+	 * Objects that have a reasonable <code>equals()</code> implementation.<br>
+	 * <br>
+	 * Important: The objects should have a limited lifespan, the interning set
+	 * used by this method is unmanaged, i.e. does not clean out old entries!
+	 * Entries without strong references are still removed.
+	 * 
+	 */
+	public static Object internObject(Object toIntern)
+	{
 		if(toIntern == null)
 			return null;
 		
-		String internedString;
-		
-		WeakStringEntry checkEntry = new WeakStringEntry(toIntern);
+		Object internedItem;
 		
-		synchronized( managedInterningSet ){
-
-			sanitize(false);
-
-			WeakStringEntry internedEntry = (WeakStringEntry) managedInterningSet.get(checkEntry);
-
-			if (internedEntry == null || (internedString = internedEntry.getString()) == null)
-			{
-				internedString = toIntern;
-				if(!managedInterningSet.add(checkEntry))
-					System.out.println("unexpected modification");  // should not happen
-			} else
+		WeakEntry checkEntry = new WeakEntry(toIntern,unmanagedRefQueue);
+	
+		synchronized( unmanagedInterningSet ){
+			
+			WeakEntry internedEntry = (WeakEntry) unmanagedInterningSet.get(checkEntry);
+			
+			if (internedEntry == null || (internedItem = (internedEntry.get())) == null)
 			{
-				internedEntry.incHits();
-				checkEntry.destroy();
-				if(TRACE_MULTIHITS && internedEntry.hits % 10 == 0)
-					System.out.println("multihit "+internedEntry);
+				internedItem = toIntern;
+				if(!unmanagedInterningSet.add(checkEntry))
+					System.out.println("unexpected modification"); // should not happen
 			}
-
+			
+			sanitizeLight();
 		}
 		
 		// should not happen
-		if(!toIntern.equals(internedString))
+		if(!toIntern.equals(internedItem))
 			System.err.println("mismatch");
 		
-		return internedString;
+		return internedItem;
 	}
-	
-	public static byte[] internBytes(byte[] toIntern) {
+
+	public static String intern(String toIntern) {
 		
 		if(toIntern == null)
 			return null;
 		
-		byte[] internedArray;
+		String internedString;
 		
-		WeakByteArrayEntry checkEntry = new WeakByteArrayEntry(toIntern);
+		WeakStringEntry checkEntry = new WeakStringEntry(toIntern);
 
-		synchronized( managedInterningSet){
-			
-			sanitize(false);
+		WeakStringEntry internedEntry = null;
+		boolean hit = false;
+		
+		managedSetLock.readLock().lock();
+		try {
 			
-			WeakByteArrayEntry internedEntry = (WeakByteArrayEntry) managedInterningSet.get(checkEntry);
+			internedEntry = (WeakStringEntry) managedInterningSet.get(checkEntry);
 			
-			if (internedEntry == null || (internedArray = internedEntry.getArray()) == null)
-			{
-				internedArray = toIntern;
-				if(!managedInterningSet.add(checkEntry))
-					System.out.println("unexpected modification");  // should not happen
-			} else
+			if (internedEntry != null && (internedString = internedEntry.getString()) != null)
+				hit = true;
+			else
 			{
-				internedEntry.incHits();
-				checkEntry.destroy();
-				if(TRACE_MULTIHITS && internedEntry.hits % 10 == 0)
-					System.out.println("multihit"+internedEntry);
+				managedSetLock.readLock().unlock();
+				managedSetLock.writeLock().lock();
+				
+				sanitize(false);
+				
+				// get again, weakrefs might have expired and been added by another thread concurrently
+				internedEntry = (WeakStringEntry) managedInterningSet.get(checkEntry);
+
+				if (internedEntry != null && (internedString = internedEntry.getString()) != null)
+					hit = true;
+				else {
+					managedInterningSet.add(checkEntry);
+					internedString = toIntern;
+				}
+				managedSetLock.readLock().lock();
+				managedSetLock.writeLock().unlock();
+
 			}
+		} finally {
+			managedSetLock.readLock().unlock();
 		}
 		
-		// should not happen
-		if(!Arrays.equals(toIntern, internedArray))
-			System.err.println("mismatch");
+		if(hit) {
+			internedEntry.incHits();
+			checkEntry.destroy();
+			if(TRACE_MULTIHITS && internedEntry.hits % 10 == 0)
+				System.out.println("multihit "+internedEntry);
+		}
+
 		
-		return internedArray;
+		return internedString;
 	}
 	
-	/**
-	 * A generic interning facilty for heavyweight or frequently duplicated
-	 * Objects that have a reasonable <code>equals()</code> implementation.<br>
-	 * <br>
-	 * Important: The objects should have a limited lifespan, the interning set
-	 * used by this method is unmanaged, i.e. does not clean out old entries!
-	 * Entries without strong references are still removed.
-	 * 
-	 */
-	public static Object internObject(Object toIntern)
-	{
+	public static byte[] internBytes(byte[] toIntern) {
+		
 		if(toIntern == null)
 			return null;
 		
-		Object internedItem;
+		byte[] internedArray;
 		
-		WeakEntry checkEntry = new WeakEntry(toIntern,unmanagedRefQueue);
+		WeakByteArrayEntry checkEntry = new WeakByteArrayEntry(toIntern);
 
-		synchronized( unmanagedInterningSet ){
-			
-			WeakEntry internedEntry = (WeakEntry) unmanagedInterningSet.get(checkEntry);
-			
-			if (internedEntry == null || (internedItem = (internedEntry.get())) == null)
+		WeakByteArrayEntry internedEntry = null;
+		boolean hit = false;
+		managedSetLock.readLock().lock();
+		try
+		{
+			internedEntry = (WeakByteArrayEntry) managedInterningSet.get(checkEntry);
+			if (internedEntry != null && (internedArray = internedEntry.getArray()) != null)
+				hit = true;
+			else
 			{
-				internedItem = toIntern;
-				if(!unmanagedInterningSet.add(checkEntry))
-					System.out.println("unexpected modification"); // should not happen
+				managedSetLock.readLock().unlock();
+				managedSetLock.writeLock().lock();
+				sanitize(false);
+				// get again, weakrefs might have expired and been added by another thread concurrently
+				internedEntry = (WeakByteArrayEntry) managedInterningSet.get(checkEntry);
+				if (internedEntry != null && (internedArray = internedEntry.getArray()) != null)
+					hit = true;
+				else
+				{
+					managedInterningSet.add(checkEntry);
+					internedArray = toIntern;
+				}
+				managedSetLock.readLock().lock();
+				managedSetLock.writeLock().unlock();
 			}
-			
-			sanitizeLight();
+		} finally
+		{
+			managedSetLock.readLock().unlock();
 		}
+		if (hit)
+		{
+			internedEntry.incHits();
+			checkEntry.destroy();
+			if (TRACE_MULTIHITS && internedEntry.hits % 10 == 0)
+				System.out.println("multihit " + internedEntry);
+		}		
 		
 		// should not happen
-		if(!toIntern.equals(internedItem))
+		if(!Arrays.equals(toIntern, internedArray))
 			System.err.println("mismatch");
 		
-		return internedItem;
+		return internedArray;
 	}
 	
 	/**
@@ -239,24 +285,42 @@ StringInterner
 		
 		WeakFileEntry checkEntry = new WeakFileEntry(toIntern);
 
-		synchronized( managedInterningSet ){
-			
-			sanitize(false);
-					
-			WeakFileEntry internedEntry = (WeakFileEntry) managedInterningSet.get(checkEntry);
-			
-			if (internedEntry == null || (internedFile = internedEntry.getFile()) == null)
-			{
-				internedFile = toIntern;
-				if(!managedInterningSet.add(checkEntry))
-					System.out.println("unexpected modification"); // should not happen
-			} else
+		WeakFileEntry internedEntry = null;
+		boolean hit = false;
+		managedSetLock.readLock().lock();
+		try
+		{
+			internedEntry = (WeakFileEntry) managedInterningSet.get(checkEntry);
+			if (internedEntry != null && (internedFile = internedEntry.getFile()) != null)
+				hit = true;
+			else
 			{
-				internedEntry.incHits();
-				checkEntry.destroy();
-				if(TRACE_MULTIHITS && internedEntry.hits % 10 == 0)
-					System.out.println("multihit"+internedEntry);
+				managedSetLock.readLock().unlock();
+				managedSetLock.writeLock().lock();
+				sanitize(false);
+				// get again, weakrefs might have expired and been added by another thread concurrently
+				internedEntry = (WeakFileEntry) managedInterningSet.get(checkEntry);
+				if (internedEntry != null && (internedFile = internedEntry.getFile()) != null)
+					hit = true;
+				else
+				{
+					managedInterningSet.add(checkEntry);
+					internedFile = toIntern;
+				}
+				managedSetLock.readLock().lock();
+				managedSetLock.writeLock().unlock();
 			}
+		} finally
+		{
+			managedSetLock.readLock().unlock();
+		}
+		
+		if (hit)
+		{
+			internedEntry.incHits();
+			checkEntry.destroy();
+			if (TRACE_MULTIHITS && internedEntry.hits % 10 == 0)
+				System.out.println("multihit " + internedEntry);
 		}
 		
 		// should not happen
@@ -275,24 +339,43 @@ StringInterner
 		
 		WeakURLEntry checkEntry = new WeakURLEntry(toIntern);
 
-		synchronized( managedInterningSet ){
-			
-			sanitize(false);
-					
-			WeakURLEntry internedEntry = (WeakURLEntry) managedInterningSet.get(checkEntry);
-			
-			if (internedEntry == null || (internedURL = internedEntry.getURL()) == null)
-			{
-				internedURL = toIntern;
-				if(!managedInterningSet.add(checkEntry))
-					System.out.println("unexpected modification"); // should not happen
-			} else
+		WeakURLEntry internedEntry = null;
+		boolean hit = false;
+		managedSetLock.readLock().lock();
+		try
+		{
+			internedEntry = (WeakURLEntry) managedInterningSet.get(checkEntry);
+			if (internedEntry != null && (internedURL = internedEntry.getURL()) != null)
+				hit = true;
+			else
 			{
-				internedEntry.incHits();
-				checkEntry.destroy();
-				if(TRACE_MULTIHITS && internedEntry.hits % 10 == 0)
-					System.out.println("multihit"+internedEntry);
+				managedSetLock.readLock().unlock();
+				managedSetLock.writeLock().lock();
+				sanitize(false);
+				// get again, weakrefs might have expired and been added by another thread concurrently
+				internedEntry = (WeakURLEntry) managedInterningSet.get(checkEntry);
+				if (internedEntry != null && (internedURL = internedEntry.getURL()) != null)
+					hit = true;
+				else
+				{
+					managedInterningSet.add(checkEntry);
+					internedURL = toIntern;
+				}
+				
+				managedSetLock.readLock().lock();
+				managedSetLock.writeLock().unlock();
 			}
+		} finally
+		{
+			managedSetLock.readLock().unlock();
+		}
+		
+		if (hit)
+		{
+			internedEntry.incHits();
+			checkEntry.destroy();
+			if (TRACE_MULTIHITS && internedEntry.hits % 10 == 0)
+				System.out.println("multihit " + internedEntry);
 		}
 		
 		// should not happen
@@ -326,98 +409,82 @@ StringInterner
 												
 	private static void sanitize(boolean scheduled)
 	{
-		synchronized( managedInterningSet ){
-			
-			WeakWeightedEntry ref;
-			while((ref = (WeakWeightedEntry)(managedRefQueue.poll())) != null)
+		WeakWeightedEntry ref;
+		while ((ref = (WeakWeightedEntry) (managedRefQueue.poll())) != null)
+		{
+			if (!ref.isDestroyed())
 			{
-				if(!ref.isDestroyed())
-				{
-					managedInterningSet.remove(ref);
-					if(TRACE_CLEANUP && ref.hits > 30)
-						System.out.println("queue remove:"+ref);
-				} else
-				{// should not happen
-					System.err.println("double removal "+ref);					
-				}
+				managedInterningSet.remove(ref);
+				if (TRACE_CLEANUP && ref.hits > 30)
+					System.out.println("queue remove:" + ref);
+			} else
+			{// should not happen
+				System.err.println("double removal " + ref);
 			}
-				
-			
-			int currentSetSize = managedInterningSet.size();
-			
-			aging:
+		}
+		int currentSetSize = managedInterningSet.size();
+		aging:
+		{
+			cleanup:
 			{
-				cleanup:
+				// unscheduled cleanup/aging only in case of emergency
+				if (currentSetSize < IMMEDIATE_CLEANUP_TRIGGER && !scheduled)
+					break aging;
+				if (TRACE_CLEANUP)
+					System.out.println("Doing cleanup " + currentSetSize);
+				ArrayList remaining = new ArrayList();
+				// remove objects that aren't shared by multiple holders first (interning is useless)
+				for (Iterator it = managedInterningSet.iterator(); it.hasNext();)
 				{
-					// unscheduled cleanup/aging only in case of emergency
-					if (currentSetSize < IMMEDIATE_CLEANUP_TRIGGER && !scheduled)
+					if (managedInterningSet.size() < IMMEDIATE_CLEANUP_GOAL && !scheduled)
 						break aging;
-					
-					if (TRACE_CLEANUP)
-						System.out.println("Doing cleanup " + currentSetSize);
-					
-					ArrayList remaining = new ArrayList();
-					
-					// remove objects that aren't shared by multiple holders first (interning is useless)
-					for (Iterator it = managedInterningSet.iterator(); it.hasNext();)
+					WeakWeightedEntry entry = (WeakWeightedEntry) it.next();
+					if (entry.hits == 0)
 					{
-						if (managedInterningSet.size() < IMMEDIATE_CLEANUP_GOAL && !scheduled)
-							break aging;
-						WeakWeightedEntry entry = (WeakWeightedEntry) it.next();
-						if (entry.hits == 0)
-						{
-							if (TRACE_CLEANUP)
-								System.out.println("0-remove: " + entry);
-							it.remove();
-						} else
-							remaining.add(entry);
-					}
-					
-					currentSetSize = managedInterningSet.size();
-					if (currentSetSize < SCHEDULED_CLEANUP_TRIGGER && scheduled)
-						break cleanup;
-					if (currentSetSize < IMMEDIATE_CLEANUP_GOAL && !scheduled)
-						break aging;
-					
-					Collections.sort(remaining, savingsComp);
-					// remove those objects that saved the least amount first
-					weightedRemove: for (int i = 0; i < remaining.size(); i++)
-					{
-						currentSetSize = managedInterningSet.size();
-						if (currentSetSize < SCHEDULED_CLEANUP_GOAL && scheduled)
-							break weightedRemove;
-						if (currentSetSize < IMMEDIATE_CLEANUP_GOAL && !scheduled)
-							break aging;
-						WeakWeightedEntry entry = (WeakWeightedEntry) remaining.get(i);
 						if (TRACE_CLEANUP)
-							System.out.println("weighted remove: " + entry);
-						managedInterningSet.remove(entry);
-					}
+							System.out.println("0-remove: " + entry);
+						it.remove();
+					} else
+						remaining.add(entry);
 				}
-			
-			
 				currentSetSize = managedInterningSet.size();
-				if (currentSetSize < SCHEDULED_AGING_THRESHOLD && scheduled)
-					break aging;
+				if (currentSetSize < SCHEDULED_CLEANUP_TRIGGER && scheduled)
+					break cleanup;
 				if (currentSetSize < IMMEDIATE_CLEANUP_GOAL && !scheduled)
 					break aging;
-				for (Iterator it = managedInterningSet.iterator(); it.hasNext();)
-					((WeakWeightedEntry) it.next()).decHits();
-			}
-			
-			if(TRACE_CLEANUP && scheduled)
-			{
-				List weightTraceSorted = new ArrayList(managedInterningSet);
-				Collections.sort(weightTraceSorted,savingsComp);
-				System.out.println("Remaining elements after cleanup:");
-				for(Iterator it = weightTraceSorted.iterator();it.hasNext();)
-					System.out.println("\t"+it.next());
+				Collections.sort(remaining, savingsComp);
+				// remove those objects that saved the least amount first
+				weightedRemove: for (int i = 0; i < remaining.size(); i++)
+				{
+					currentSetSize = managedInterningSet.size();
+					if (currentSetSize < SCHEDULED_CLEANUP_GOAL && scheduled)
+						break weightedRemove;
+					if (currentSetSize < IMMEDIATE_CLEANUP_GOAL && !scheduled)
+						break aging;
+					WeakWeightedEntry entry = (WeakWeightedEntry) remaining.get(i);
+					if (TRACE_CLEANUP)
+						System.out.println("weighted remove: " + entry);
+					managedInterningSet.remove(entry);
+				}
 			}
-			
-			if(scheduled)
-				managedInterningSet.compactify(-1f);
-				
-		}
+			currentSetSize = managedInterningSet.size();
+			if (currentSetSize < SCHEDULED_AGING_THRESHOLD && scheduled)
+				break aging;
+			if (currentSetSize < IMMEDIATE_CLEANUP_GOAL && !scheduled)
+				break aging;
+			for (Iterator it = managedInterningSet.iterator(); it.hasNext();)
+				((WeakWeightedEntry) it.next()).decHits();
+		}
+		if (TRACE_CLEANUP && scheduled)
+		{
+			List weightTraceSorted = new ArrayList(managedInterningSet);
+			Collections.sort(weightTraceSorted, savingsComp);
+			System.out.println("Remaining elements after cleanup:");
+			for (Iterator it = weightTraceSorted.iterator(); it.hasNext();)
+				System.out.println("\t" + it.next());
+		}
+		if (scheduled)
+			managedInterningSet.compactify(-1f);				
 	}
 
 	private static class WeakEntry extends WeakReference {
diff --git a/org/gudy/azureus2/core3/util/SystemTime.java b/org/gudy/azureus2/core3/util/SystemTime.java
index 06ec94f..e77f19c 100644
--- a/org/gudy/azureus2/core3/util/SystemTime.java
+++ b/org/gudy/azureus2/core3/util/SystemTime.java
@@ -18,7 +18,10 @@
  */
 package org.gudy.azureus2.core3.util;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * Utility class to retrieve current system time, and catch clock backward time
@@ -27,6 +30,12 @@ import java.util.*;
 public class SystemTime {
 	public static final long			TIME_GRANULARITY_MILLIS	= 25;	//internal update time ms
 	private static SystemTimeProvider	instance;
+	
+	// can't do that without some safeguarding code.
+	// monotime does guarantee that time neither goes backwards nor performs leaps into the future.
+	// the HPC doesn't jump backward but can jump forward in time
+	private static final boolean		SOD_IT_LETS_USE_HPC = false;//	= Constants.isCVSVersion();
+	
 	static
 	{
 		try
@@ -73,10 +82,13 @@ public class SystemTime {
 
 	protected static class SteppedProvider implements SystemTimeProvider {
 		private static final int	STEPS_PER_SECOND	= (int) (1000 / TIME_GRANULARITY_MILLIS);
+		private static final long	HPC_START = getHighPrecisionCounter()/1000000L;
+		
 		private final Thread		updater;
 		private volatile long		stepped_time;
 		private volatile long		currentTimeOffset = System.currentTimeMillis();
-		private volatile long		last_approximate_time;
+		private AtomicLong 			last_approximate_time = new AtomicLong(); 
+		//private volatile long		last_approximate_time;
 		private volatile int		access_count;
 		private volatile int		slice_access_count;
 		private volatile int		access_average_per_slice;
@@ -213,30 +225,47 @@ public class SystemTime {
 		}
 
 		public long getMonoTime() {
-			long adjusted_time = stepped_time;
-			long averageSliceStep = access_average_per_slice;
-			if (averageSliceStep > 0)
-			{
-				long sliceStep = (drift_adjusted_granularity * slice_access_count) / averageSliceStep;
-				if (sliceStep >= drift_adjusted_granularity)
+			if ( SOD_IT_LETS_USE_HPC ){
+				
+				return( ( getHighPrecisionCounter()/1000000) - HPC_START );
+				
+			}else{
+				long adjusted_time;
+				long averageSliceStep = access_average_per_slice;
+				if (averageSliceStep > 0)
 				{
-					sliceStep = drift_adjusted_granularity - 1;
-				}
-				adjusted_time += sliceStep;
+					long sliceStep = (drift_adjusted_granularity * slice_access_count) / averageSliceStep;
+					if (sliceStep >= drift_adjusted_granularity)
+					{
+						sliceStep = drift_adjusted_granularity - 1;
+					}
+					adjusted_time = sliceStep + stepped_time;
+				} else
+					adjusted_time = stepped_time;
+				access_count++;
+				slice_access_count++;
+	
+				// make sure we don't go backwards and our reference value for going backwards doesn't go backwards either
+				long approxBuffered = last_approximate_time.get(); 
+				if (adjusted_time < approxBuffered)
+					adjusted_time = approxBuffered;				
+				else
+					last_approximate_time.compareAndSet(approxBuffered, adjusted_time);
+	
+				return adjusted_time;
 			}
-			access_count++;
-			slice_access_count++;
-			// make sure we don't go backwards
-			if (adjusted_time < last_approximate_time)
-				adjusted_time = last_approximate_time;
-			else
-				last_approximate_time = adjusted_time;
-			return adjusted_time;
 		}
 		
 		public long getSteppedMonoTime() {
 
-			return( stepped_mono_time );
+			if ( SOD_IT_LETS_USE_HPC ){
+				
+				return( getHighPrecisionCounter()/1000000 );
+				
+			}else{
+				
+				return( stepped_mono_time );
+			}
 		}
 	}
 	
@@ -349,9 +378,6 @@ public class SystemTime {
 	 * 
 	 * <b>Do not mix times retrieved by this method with normal time!</b>
 	 * 
-	 * TODO once we move to java 1.5 use atomic stuff to harden the guarantee
-	 * (multithreaded access can weaken it at the moment)
-	 * 
 	 * @return the amount of real time passed since the program start in
 	 *         milliseconds
 	 */
@@ -360,7 +386,7 @@ public class SystemTime {
 	}
 
 		/**
-		 * Like getMonotonousTime but only updated at TIME_GRANULARITY_MILLIS intervals (not interopolated)
+		 * Like getMonotonousTime but only updated at TIME_GRANULARITY_MILLIS intervals (not interpolated)
 		 * As such it is likely to be cheaper to obtain
 		 * @return
 		 */
diff --git a/org/gudy/azureus2/core3/util/TorrentUtils.java b/org/gudy/azureus2/core3/util/TorrentUtils.java
index b4f3f80..7847d6f 100644
--- a/org/gudy/azureus2/core3/util/TorrentUtils.java
+++ b/org/gudy/azureus2/core3/util/TorrentUtils.java
@@ -1601,6 +1601,13 @@ TorrentUtils
 			return( delegate.getCreatedBy());
 		}
 		
+	 	public void
+		setCreatedBy(
+			byte[]		cb )
+	   	{
+	  		delegate.setCreatedBy( cb );
+	   	}
+	 	
 		public boolean
 		isCreated()
 		{
diff --git a/org/gudy/azureus2/internat/MessagesBundle.properties b/org/gudy/azureus2/internat/MessagesBundle.properties
index 8c13f43..84327e7 100644
--- a/org/gudy/azureus2/internat/MessagesBundle.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle.properties
@@ -764,7 +764,6 @@ ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=This option will refres
 #
 #2.0.7.0
 #
-ConfigView.section.style.verticaloffset=Graphics Vertical Offset (GTK fix)
 security.certtruster.title=Security Certificate Warning
 security.certtruster.intro=The security certificate was issued by a company you do not trust
 security.certtruster.resource=Resource:
@@ -1029,7 +1028,7 @@ GenericText.column=column
 MyTorrentsView.menu.thisColumn.remove=Remove Column
 MyTorrentsView.menu.thisColumn.toClipboard=Copy Text To Clipboard
 MyTorrentsView.menu.thisColumn.autoTooltip=Always display tooltip
-MyTorrentsView.menu.tracker=Tracker
+MyTorrentsView.menu.tracker=Tracker/Torrent
 ConfigView.download.abbreviated=D:
 ConfigView.upload.abbreviated=U:
 ConfigView.complete.abbreviated=C:
@@ -2099,19 +2098,17 @@ ConfigView.section.connection.udp.enable=Enable UDP
 ConfigView.section.style.showiconbar=Show Toolbar
 MainWindow.menu.view.iconbar=Toolbar
 
-MyTorrentsView.menu.rename=Rename
+MyTorrentsView.menu.rename=Rename...
 MyTorrentsView.menu.rename.displayed=Rename Displayed Name
 MyTorrentsView.menu.rename.save_path=Rename Save Path
-MyTorrentsView.menu.rename.displayed_and_save_path=Rename Both
 
-MyTorrentsView.menu.rename.displayed.enter.title=Rename Displayed Name 
-MyTorrentsView.menu.rename.displayed.enter.message=Enter a new name to display for this download.\nIf no text is entered, the original name will be used.
+AdvRenameWindow.title=Rename Download 
+AdvRenameWindow.message=Enter a new name for this download.
+AdvRenameWindow.rename.torrent=Rename Torrent
 
-MyTorrentsView.menu.rename.save_path.enter.title=Rename Save Path 
-MyTorrentsView.menu.rename.save_path.enter.message=Enter a new save path name for this download.\nIf no text is entered, the download's displayed name will be used.
+MyTorrentsView.menu.rename.displayed.enter.title=Rename Displayed Name 
+MyTorrentsView.menu.rename.displayed.enter.message=Enter a new name to display for this download.
 
-MyTorrentsView.menu.rename.displayed_and_save_path.enter.title=Rename Download 
-MyTorrentsView.menu.rename.displayed_and_save_path.enter.message=Enter a new name for this download.\nIf no text is entered, the original values will be used.
 
 MyTorrentsView.menu.edit_comment=Edit Comment
 MyTorrentsView.menu.edit_comment.enter.title=Edit Comment
@@ -2396,7 +2393,6 @@ v3.MainWindow.button.comment=Comment
 v3.MainWindow.button.viewdetails=View Details
 v3.MainWindow.button.play=Play
 v3.MainWindow.button.cancel=Cancel
-v3.MainWindow.button.sendtofriend=Share Torrent
 v3.MainWindow.button.preview=Preview
 
 v3.MainWindow.view.wait=Initializing view, please wait.
@@ -2520,8 +2516,8 @@ PeerSocket.unknown=Unknown
 PeerSocket.fake_client=FAKE
 PeerSocket.bad_peer_id=bad peer ID
 PeerSocket.mismatch_id=mismatch
-PeerSocket.unknown_az_style=Unknown %1/%2
-PeerSocket.unknown_shadow_style=Unknown %1/%2
+PeerSocket.unknown_az_style=Unknown %1 %2
+PeerSocket.unknown_shadow_style=Unknown %1 %2
 
 OpenTorrentWindow.mb.askCreateDir.title=Destination Directory does not exist
 OpenTorrentWindow.mb.askCreateDir.text=The destination directory '%1' does not exist.\n\nCreate now?
@@ -2689,7 +2685,7 @@ v3.MainWindow.tab.events=Notifications
 button.columnsetup.tooltip=Column Setup
 
 v3.activity.remove.title=Delete Notification
-v3.activity.remove.text=Are you sure you want to delete this Notification ?
+v3.activity.remove.text=Are you sure you want to delete this Notification?\n%1
  
 #v3.MainWindow.menu.view.configuration=Preferences
 #v3.MainWindow.menu.view.configuration.keybinding=Meta+,
@@ -2825,65 +2821,22 @@ Button.bar.add=Add
 Button.bar.edit=Edit
 Button.bar.edit.cancel=Done Editing
 
-v3.Share.menu=Share content
-v3.Share.header=Share
-v3.Share.header.message=Share with current Friends, or add new Friends.
-v3.Share.add.buddy=Add Friends
-v3.Share.add.edit.buddy=Add/Edit Friends
-v3.Share.add.buddy.all=Share with all
-v3.Share.add.buddy.existing=Existing Friends:
-v3.Share.add.buddy.new=New Friends:
-v3.Share.buddies=Friends
-v3.Share.invitees=Invitees
-v3.Share.invite.buddies.prompt=Invite more friends to share with
-v3.Share.send.now=Send
-v3.Share.optional.message=Optional message delivered via Notifications (maximum 140 characters):
-v3.Share.disclaimer=Note: Both the content you share, as well as this optional message will be encrypted.
-v3.Share.disclaimer.link=Read more
-
-ConfigView.section.security.vuze.login=You must be logged into Vuze to perform this operation
-
-v3.buddy.menu.viewprofile=View Profile
-v3.buddy.menu.remove=Remove Friend
 v3.MainWindow.menu.view.pluginbar=Plugin Bar
-v3.MainWindow.menu.view.buddies-viewer=Friends Bar
-
-v3.activity.buddy-request=You have a friend request from %1
-v3.activity.buddy-request.accept=Accept
-v3.activity.buddy-request.multi=You have a friend request [#%3] from %1
-v3.activity.buddy-linkup=You and %1 are now friends
-v3.activity.share-content=%1 has shared %2 with you. %3 <A HREF="%4" TITLE="%5">says...</A>
-v3.activity.share-content.no-msg=%1 has shared %2 with you
-
-v3.buddies.friends=Friends
-v3.buddies.online=Online (%1)
-v3.buddies.remove=Remove friend
-v3.buddies.add.to.share=Add friend to Share
 
 MainWindow.dialog.select.vuze.file=Select Vuze File
 MainWindow.menu.file.open.vuze=Vuze File...
 
-azbuddy.ui.dialog.disable.title=Disable Friends Plugin
-azbuddy.ui.dialog.disable.text=Disabling the Friends plugin will prevent you from sharing torrents via the Friends Bar at the bottom of the application, and prevent you from modifying your friends list\n\nAre you sure you want to disable Friends?
-
 metasearch.addtemplate.title=Install Search Template?
 metasearch.addtemplate.desc=Are you sure you want to install a search template named '%1'?
 
 v3.share.private.title=Sharing Torrent
 v3.share.private.text=The selected torrent is marked as a Private Torrent.\n\nYou can not share private torrents.
 
-v3.buddies.disabled.title=Friends Plugin Disabled
-v3.buddies.disabled.text._windows=You have disabled the friends plugin, which will prevent you from sharing or accepting torrents or friend requests. You can change your settings in the Options tab.
-v3.buddies.disabled.text._mac=You have disabled the friends plugin, which will prevent you from sharing or accepting torrents or friend requests. You can change your settings in the Options tab.
-
 metasearch.addtemplate.dup.title=Duplicate Template
 metasearch.addtemplate.dup.desc=Search template %1 is already installed
 metasearch.export.select.template.file=Save Template
 metasearch.import.select.template.file=Open Template
 
-v3.MainWindow.button.newtag.share=New! Share Torrent
-v3.buddies.faq=Read more
-
 dialog.uiswitch.title=Switch to Vuze UI
 dialog.uiswitch.text=You need to be running the Vuze UI to use this feature.\n\nVuze will need to restart.
 dialog.uiswitch.button=Switch to the Vuze UI
@@ -2894,27 +2847,11 @@ azbuddy.protocolspeed=KB/s max friend protocol overhead
 v3.MainWindow.button.download=Download
 v3.MainWindow.button.run=Launch Downloaded File 
 
-v3.activity.header.friend.requests.foryou=Friend Requests - For You
-v3.activity.header.friend.requests.fromyou=Friend Requests - From You
-v3.activity.header.friend.requests.accepted=Friend Requests - Accepted
-v3.activity.header.share.requests=Share Torrent Requests
 v3.activity.header.downloads=Downloads
-v3.activity.header.rating.reminders=Rating Reminders
 v3.activity.header.vuze.news=Vuze News
 
-login.optional.message=You must be signed in to use this feature
-
-message.confirm.share.singular=Excellent!  Your request to share a torrent has been sent.
-message.confirm.share.plural=Excellent!  Your requests to share a torrent have been sent.
-message.confirm.share.invite.singular=Excellent!  Your request to connect and share has been sent.  Feel free to gently coax your friend to accept.
-message.confirm.share.invite.plural=Excellent!  Your requests to connect and share have been sent.  Feel free to gently coax your friend to accept.
-message.confirm.invite.singular=Excellent!  Your Friend request has been sent.  Feel free to gently coax your friend to accept.
-message.confirm.invite.plural=Excellent!  Your Friend requests have been sent.  Feel free to gently coax your friends to accept.
-message.confirm.invite.error=Doh!  Some wires got crossed on this request.  One or more of your invites had errors.
-message.prompt.add.friends=Select friends from your Sidebar (on the lower-left).
 message.taking.too.long=It appears that this is taking longer than expected\nPress 'ESC' if you wish to cancel this operation
 message.status.success=Success
-message.intro.friends=Add Friends.\nShare Torrents.\nDownload Faster.
 
 azbuddy.tracker.bbb.status.title=Friend Boost
 azbuddy.tracker.bbb.status.title.tooltip=Double-click for details
@@ -2926,16 +2863,9 @@ azbuddy.tracker.bbb.status.out=Currently Boosting Friends
 v3.MainWindow.search.go.tooltip=Execute Search
 v3.MainWindow.search.last.tooltip=Return to search results
 
-v3.activity.buddy-invited=You have sent a Friend request to %1.
-v3.activity.buddy-invited.multi=You have sent a Friend request to the following people:\n%1
-
 metasearch.addtemplate.done.title=Template Added
 metasearch.addtemplate.done.desc=Template '%1' added successfully.\nIt will be used when you next search!
 
-v3.MainWindow.button.share=Share Content
-v3.buddies.remove.buddy.dialog.title=Remove
-v3.buddies.remove.buddy.dialog.text=Do you really want to remove %1 as a Friend?
-
 
 ConfigView.section.security.nopw=No password was supplied
 ConfigView.section.security.nopw_v=No password available, please sign into Vuze
@@ -2955,17 +2885,8 @@ azbuddy.os_offline=Offline
 
 azbuddy.ui.menu.disconnect=Disconnect
 
-v3.buddy.menu.chat=Chat
-
-v3.chat.offline=%1 is currently offline and will receive your message once back online.
-v3.chat.wrongversion=%1 is using a version of Vuze which does not support Chat.
 azbuddy.enable_chat_notif=Enable chat notifications
 
-v3.buddies.dnd.info.dialog.title=Drop Share
-v3.buddies.dnd.info.dialog.text=You have initiated a Drop Share.Your content is being prepared for sharing, and the share screen will open once your content is ready.\n\nYou have to keep Vuze running in order for your Friend to receive the content.\n<A HREF="http://faq.vuze.com/?View=entry&EntryID=267">Click here</A> to get more information about this feature.
-v3.buddies.dnd.info.dialog.ok=Ok
-v3.buddies.dnd.info.dialog.remember=Do not show this message again
-
 progress.window.msg.progress=Please wait while the operation completes
 
 ConfigView.section.connection.advanced.read_select=Read select timeout (millis, default %1)
@@ -3042,8 +2963,6 @@ please open the Plugin Debug log view for more information.
 
 TableColumn.header.Thumbnail=Icon
 TableColumn.header.Thumbnail.info=The thumbnail image for Vuze content; for all other content the operating system is providing these icons. 
-TableColumn.header.Rating_global=Rating
-TableColumn.header.Rating_global.info=The global rating for this content
 
 v3.MainWindow.menu.getting_started=&Getting Started
 MainWindow.menu.community=&Community
@@ -3052,7 +2971,6 @@ MainWindow.menu.help.faq.keybinding.mac=Meta+?
 MainWindow.menu.community.wiki=Community &Wiki
 MainWindow.menu.community.forums=Community Fo&rums
 MainWindow.menu.community.blog=Vuze &Blog
-MainWindow.menu.community.add_friends=&Add Friends
 MainWindow.menu.help.support=&Help and Support
 
 
@@ -3063,10 +2981,6 @@ Button.done=Done
 
 GeneralView.torrent_created_on_and_by=%1 by %2
 
-v3.Share.wizard.title=Share -- Wizard
-v3.AddFriends.header.message=Add friends to start sharing your favorite torrents
-v3.AddFriends.header=Add Friends
-v3.AddFriends.wizard.title=Add Friends -- Wizard
 Button.continue=Continue
 Button.preview=Preview
 
@@ -3084,9 +2998,6 @@ MyTorrents.bigView.header={sidebar.LibraryDL}
 authenticator.location=Location
 authenticator.details=Details
 
-v3.MainWindow.menu.publish.new=Publish New Content
-v3.MainWindow.menu.publish.mine=Your Published Content
-v3.MainWindow.menu.publish.about=About Publishing...
 v3.MainWindow.menu.showActionBarText=Show Text
 
 subscript.import.fail.title=Import Failed
@@ -3110,14 +3021,11 @@ subscriptions.config.maxresults=Maximum number of results retained per subscript
 
 v3.activity.button.readall=Mark All Read
 
-ConfigView.interface.start.library=Start in Library
-
 TableColumn.header.activityNew=New
 TableColumn.header.activityType=Type
 TableColumn.header.activityText=Message
 TableColumn.header.activityDate=Date Added
 TableColumn.header.activityActions=Actions
-TableColumn.header.activityAvatar=Avatar
 
 Subscription.menu.resetauth=Reset Authentication Details
 Search.menu.engines=Templates
@@ -3154,9 +3062,6 @@ Wizard.Subscription.subscribe.subscriptions=Related Subscriptions
 Wizard.Subscription.subscribe.library.empty=No subscriptions available?\n \nLook for the bright orange subscribe button on the Vuze HD Network.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Read more</A>
 
 
-TableColumn.header.Info=Info
-TableColumn.header.videoLength=Video Length
-
 message.confirm.delete.title=Confirm Delete
 message.confirm.delete.text=Are you sure you want to delete '%1'?\
 
@@ -3234,9 +3139,6 @@ Button.deleteContent.fromLibrary=Remove from Library
 Button.deleteContent.fromComputer=Delete from Computer
 v3.deleteContent.message=\nWould you like to delete '%1' from your computer, or just remove it from your Vuze Library?
 
-v3.library.infobar.text1=Looking for the Advanced View?
-v3.library.infobar.text2=Use the View toggle in the toolbar above.
-
 v3.MainWindow.menu.view.toolbartext=Toolbar Text
 v3.MainWindow.menu.view.asSimpleList=Simple List
 v3.MainWindow.menu.view.asAdvancedList=Advanced List
@@ -3276,16 +3178,6 @@ azbuddy.ui.menu.cat.set=Enter categories
 azbuddy.ui.menu.cat.set_msg=Comma separated list of categories, or 'All'
 azbuddy.ui.menu.cat_subs=Subscribe
 
-v3.buddy.prop.dn=Display name
-v3.buddy.prop.un=User name
-v3.buddy.prop.on=Online
-v3.buddy.prop.lupd=Last updated
-v3.buddy.prop.pks=Public key count
-v3.buddy.prop.pc=Pending chat messages
-v3.buddy.prop.catout=Your categories that friend can subscribe to
-v3.buddy.prop.catin=Friend's categories offered to you
-v3.buddy.set.catout=Allow friend to subscribe to category
-v3.buddy.set.catin=Subscribe to friend's category
 subs.prop.update_period=Update period
 azbuddy.enable_cat_pub=Public categories that ALL your friends can subscribe to (',' separated) 
 
@@ -3306,12 +3198,9 @@ TableColumn.header.category.info=Name of the category that the torrent belongs t
 TableColumn.header.DateCompleted.info=Date that the torrent downloading was completed
 TableColumn.header.AzProduct.info=Content Network that the torrent originated from
 TableColumn.header.health.info=How healthy your connection to the torrent's swarm is
-TableColumn.header.Info.info=Button that launches the details page of Vuze Content
 TableColumn.header.maxuploads.info=Maximum # of peers to simultaneously upload to
 TableColumn.header.name.info=Name of torrent
 TableColumn.header.unopened.info=Flag to indicate whether the torrent has been played (opened)
-TableColumn.header.Quality.info=Quality of vuze content, such as HD, SD 
-TableColumn.header.RateIt.info=Ability to rate vuze content
 TableColumn.header.savepath.info=The destination folder or file for the torrent's data
 TableColumn.header.SeedingRank.info=Ranking value of how badly the torrent needs seeding.  Higher value means higher need.
 TableColumn.header.shareRatio.info=How much you've upload (shared) in comparison to how much you downloaded.
@@ -3321,7 +3210,6 @@ TableColumn.header.upspeed.info=Current upload speed
 TableColumn.header.downspeed.info=Current download speed 
 TableColumn.header.up.info=Current amount of data sent to other users
 TableColumn.header.down.info=Current amount of data received from other users
-TableColumn.header.videoLength.info=Play time of vuze video content
 TableColumn.header.ProgressETA.info=Combines Status, Completion, ETA, and Down Speed columns into one multi-lined column.
 TableColumn.header.eta.info=Estimated time before torrent is done downloaded
 Pieces.column.#=#
@@ -3525,7 +3413,7 @@ devices.copy.folder.dest=Copy to folder
 TableColumn.menu.maxuploads=# Max Uploads
 devices.xcode.mancopy=Manually Copy Files
 devices.xcode.show.cat=Separate By Category
-ConfigView.label.alwaysShowLibraryHeader=Always show header in Library (My Torrents)
+ConfigView.label.alwaysShowLibraryHeader=Always show header/filter bar in Library (My Torrents)
 devices.cat.show=Show categories
 devices.tivo.machine=TiVo machine name
 
@@ -3546,4 +3434,117 @@ devices.info.copypending2=%1 File(s) Waiting To Be Copied, Connect Your Device
 subscriptions.column.nb-subscribers=Subscribers
 subscriptions.column.category={TableColumn.header.category}
 
+device.offlinedownloader.view.title=Offline Downloaders
+device.xcode.group={device.xcode}
+device.od.group={device.offlinedownloader.view.title}
+device.od.enable=Enable offline download devices
+device.odauto.enable=Automatically manage downloads
+device.odpt.enable=Include private torrents
+devices.contextmenu.od=Offline Downloading
+devices.contextmenu.od.auto=<Automatic>
+devices.contextmenu.od.enable=Enable
+devices.contextmenu.od.enabled=Enabled
+
+devices.od.view.heading=Downloads scheduled for offline downloading
+DevicesOD.column.od_name={TableColumn.header.name}
+DevicesOD.column.od_status={MyTrackerView.status}
+DevicesOD.column.od_completion=Transfer Progress
+DevicesOD.column.od_remaining={TableColumn.header.remaining}
+devices.od.xfering={PeersView.BlockView.Transfer}
+devices.od.idle=Idle
+
+device.od.turnon.title=Turn On Offline Downloader Support
+device.is.disabled=Device is disabled
+device.configure=Configure...
+
+device.od.error.notfound=Device appears to be offline
+device.od.error.opfailstatus=Device failed to process command %1: status %2
+device.od.error.opfailexcep=Device failed to process command %1: exception %2
+device.od.error.nospace=No space left on device or no external drive connected
+device.od.space=Available Space
+
+ConfigView.section.style.forceSIValues=Force values to be shown as IEC values regardless of display unit for legacy purposes (e.g. 1MB = 1MiB = 1048576B)
+
+ConfigView.label.enableSystrayToolTip=Show download stats on hover
+
+devices.activation=Device Activation
+button.nothanks=No Thanks
+devices.od.turnon.text1=We have noticed that you are connected to a %1.
+devices.od.turnon.text2=Would you like the %1 to continue to download your files when your computer is offline?
+devices.od.turnon.text3=Please connect a Hard Drive to the %1 to turn on this feature.
+devices.od.turnon.learn=Learn more >
+devices.router=router
+devices.od=offline downloader
+webui.pairingenable=Enable pairing
+webui.group.access=Access Control
+
+ConfigView.section.Pairing=Pairing
+pairing.accesscode=Access code
+pairing.ac.getnew=Allocate a new access code
+pairing.ac.getnew.create=Create
+pairing.ipv4=IPv4 address
+pairing.ipv6=IPv6 address
+pairing.host=Host address (DNS name)
+
+pairing.group.explicit=Explicit Attributes
+pairing.explicit.enable=Enable
+pairing.explicit.info=Normally explicit IP attributes do not need to be specified as these can be automatically derived.\nThe 'host' attribute can be used, for example, if you have a DynDNS account and appropriate client software to keep your dynamic IP correctly registered.
+
+pairing.op.fail=Pairing Operation Failed
+pairing.alloc.fail=Failed to allocate a new access code\n%1
+pairing.enable=Enable pairing of Vuze and remote applications/interfaces
+pairing.status.info=Status
+pairing.status.registered=Update successful (%1)
+pairing.status.pending=Update will be performed at %1
+pairing.status.initialising=Initialising
+pairing.status.disabled=Disabled
+pairing.view.registered=Click to view current registration details
+webui.pairing.info.n=Pairing is disabled, see the Connection->Pairing options for information on this feature 
+webui.pairing.info.y=Pairing is enabled, see the Connection->Pairing options for more details.
+webui.enable=Enable (*)
+ConfigView.section.rss=Local RSS etc.
+subscriptions.rss.enable=Create RSS Feeds from subscrptions
+device.tivo.enable=Enable TiVo support
+
+Button.removeAll=Remove All
+
+label.rename=Rename %1
+
+RCM.column.rc_new={TableColumn.header.unopened}
+RCM.column.rc_rank=Rank
+RCM.column.rc_actions={TableColumn.header.activityActions}
+RCM.column.rc_created=Created
+RCM.column.rc_hash=Hash
+RCM.column.rc_lastseen=Last Seen
+RCM.column.rc_level=Level
+RCM.column.rc_peers={TableColumn.header.peers}
+RCM.column.rc_seeds={TableColumn.header.seeds}
+RCM.column.rc_size={TableColumn.header.size}
+RCM.column.rc_tracker=Tracker
+RCM.column.rc_title={TableColumn.header.name}
+rcm.view.heading=Swarm Discoveries
+rcm.view.title={rcm.view.heading}
+rcm.contextmenu.lookupassoc={rcm.view.heading}
+ConfigView.section.Associations={rcm.view.heading}
+rcm.config.enabled=Enable
+rcm.config.max_results=Maximum results
+rcm.config.max_level=Maximum level
+rcm.search.provider=Swarm
+
+pairing.server.warning.title=Pairing Server Message
+wizard.webseedseditor.edit.title=HTTP Seeds Editor
+wizard.webseedseditor.edit.newseed=New Seed
+MyTorrentsView.menu.editWebSeeds=Edit HTTP Seeds
+
+ClientStats.title.full=Client Stats
+ClientStats.column.count=Count
+ClientStats.column.discarded={PeersView.discarded}
+ClientStats.column.received={DHTView.transport.received}
+ClientStats.column.sent={DHTView.transport.sent}
+ClientStats.column.percent=%
+ClientStats.column.name={TableColumn.header.name}
+MainWindow.menu.view.clientstats={ClientStats.title.full}
+
+Scrape.status.cached=Cached scrape
+
 #PLEASE LEAVE ME AT VERY BOTTOM!
diff --git a/org/gudy/azureus2/internat/MessagesBundle_de_DE.properties b/org/gudy/azureus2/internat/MessagesBundle_de_DE.properties
index 6b7e5a0..0eac092 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_de_DE.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_de_DE.properties
@@ -701,7 +701,6 @@ ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Diese Option wird die '
 #
 #2.0.7.0
 #
-ConfigView.section.style.verticaloffset=vertikaler Versatz der Grafik (GTK fix)
 security.certtruster.title=Sicherheitszertifikatswarnung
 security.certtruster.intro=Das Sicherheitszertifikat wurde von einer Firma ausgestellt, der Du nicht vertraust 
 security.certtruster.resource=Ressource:
@@ -1857,13 +1856,11 @@ MainWindow.menu.view.iconbar=Werkzeugleiste
 MyTorrentsView.menu.rename=Umbenennen
 MyTorrentsView.menu.rename.displayed=Benenne angezeigten Namen um
 MyTorrentsView.menu.rename.save_path=Benenne Verzeichnis/Datei um
-MyTorrentsView.menu.rename.displayed_and_save_path=Benenne beides um
+AdvRenameWindow.title=Benenne Download um
+AdvRenameWindow.message=Neuen Namen f\u00fcr diesen Download eingeben.
+AdvRenameWindow.rename.torrent=Benenne Torrent um
 MyTorrentsView.menu.rename.displayed.enter.title=Umbenennung des angezeigten Namens
 MyTorrentsView.menu.rename.displayed.enter.message=Neuer Name, unter dem der Download in der Liste angezeigt wird.\nWird kein Text eingegeben, wird der Originalname verwendet.
-MyTorrentsView.menu.rename.save_path.enter.title=Umbenennung des Verzeichnisses/der Datei
-MyTorrentsView.menu.rename.save_path.enter.message=Neuer Name f\u00fcr das Verzeichnis/die Datei dieses Downloads.\nWird kein Text eingegeben, wird der vom Torrent angezeigte Name verwendet.
-MyTorrentsView.menu.rename.displayed_and_save_path.enter.title=Umbenennung des Downloads
-MyTorrentsView.menu.rename.displayed_and_save_path.enter.message=Neuer Name f\u00fcr den Download.\nWird kein Text eingegeben, wird der Originalname verwendet.
 MyTorrentsView.menu.edit_comment=Editiere Kommentar
 MyTorrentsView.menu.edit_comment.enter.title=Editiere Kommentar
 MyTorrentsView.menu.edit_comment.enter.message=Kommentiere diesen Download.
@@ -2071,7 +2068,6 @@ v3.MainWindow.button.comment=Kommentar
 v3.MainWindow.button.viewdetails=Detailansicht
 v3.MainWindow.button.play=Abspielen
 v3.MainWindow.button.cancel=Abbrechen
-v3.MainWindow.button.sendtofriend=Verteilen
 v3.MainWindow.button.preview=Vorschau
 v3.MainWindow.view.wait=Initialisiere Ansicht, bitte warten.
 v3.MainWindow.xofx=%1 von %2
@@ -2362,52 +2358,17 @@ Button.bar.share=Verteilen
 Button.bar.add=Hinzuf\u00fcgen
 Button.bar.edit=Editieren
 Button.bar.edit.cancel=Editieren abbrechen
-v3.Share.menu=Tausche Inhalt
-v3.Share.header=Tauschen
-v3.Share.header.message=Tausche diesen Inhalt...
-v3.Share.add.buddy=Freunde hinzuf\u00fcgen
-v3.Share.add.edit.buddy=Freunde hinzuf\u00fcgen/editieren
-v3.Share.add.buddy.all=W\u00e4hle alle Freunde aus
-v3.Share.add.buddy.existing=Vorhandene Freunde, mit denen getauscht werden soll:
-v3.Share.add.buddy.new=Neue Freunde, die eingeladen und mit denen getauscht werden soll:
-v3.Share.buddies=Freunde
-v3.Share.invitees=Eingeladene
-v3.Share.invite.buddies.prompt=Lade mehr Freunde zum Tauschen ein
-v3.Share.send.now=Jetzt senden
-v3.Share.optional.message=Optionale Mitteilung, als Benachrichtigung (maximal 140 Zeichen):
-v3.Share.disclaimer=Anmerkung: Sowohl der zu tauschende Inhalt, als auch diese optionale Nachricht werden verschl\u00fcsselt.
-v3.Share.disclaimer.link=Mehr erfahren...
-ConfigView.section.security.vuze.login=Einloggen in Vuze notwendig, um diese Aufgabe durchzuf\u00fchren
-v3.buddy.menu.viewprofile=Profil ansehen
-v3.buddy.menu.remove=Entferne Freund
 v3.MainWindow.menu.view.pluginbar=Plugin-Leiste
-v3.MainWindow.menu.view.buddies-viewer=Freunde-Leiste
-v3.activity.buddy-request=Freundanfrage von %1
-v3.activity.buddy-request.accept=Akzeptieren
-v3.activity.buddy-request.multi=Freundanfrage [#%3] von %1
-v3.activity.buddy-linkup=Ab jetzt ist man mit %1 befreundet
-v3.activity.share-content=%1 hat %2 mit dir getauscht. %3 <A HREF="%4" TITEL="%5">sagt...</A>
-v3.activity.share-content.no-msg=%1 w\u00fcrde gerne %2 tauschen
-v3.buddies.friends=Freunde
-v3.buddies.remove=Entferne Freund
-v3.buddies.add.to.share=Freund zum Tauschen hinzuf\u00fcgen
 MainWindow.dialog.select.vuze.file=W\u00e4hle Vuze-Datei
 MainWindow.menu.file.open.vuze=Vuze-Datei...
-azbuddy.ui.dialog.disable.title=Deaktiviere Freunde-Plugin
-azbuddy.ui.dialog.disable.text=Deaktivieren des Freunde-Plugins verhindert das Tauschen von Torrents \u00fcber die Freunde-Leiste am unteren Rand der Anwendung und das Ver\u00e4ndern der Freundliste.\n\nSicher, dass das Freunde-Plugin deaktiviert werden soll?
 metasearch.addtemplate.title=Suchmaske installieren?
 metasearch.addtemplate.desc=Sicher, dass die Suchmaske '%1' installiert werden soll?
 v3.share.private.title=Zu tauschender Torrent
 v3.share.private.text=Der gew\u00e4hlte Torrent ist als privat markiert.\n\nSolche Torrents k\u00f6nnen nicht getauscht werden.
-v3.buddies.disabled.title=Freunde-Plugin deaktiviert
-v3.buddies.disabled.text._windows=Das Freunde-Plugin wurde deaktiviert, dies verhindert das Tauschen, Akzeptieren von Torrents oder Freundanfragen. Es kann unter Konfiguration ge\u00e4ndert werden.
-v3.buddies.disabled.text._mac=Das Freunde-Plugin wurde deaktiviert, dies verhindert das Tauschen, Akzeptieren von Torrents oder Freundanfragen. Es kann unter Konfiguration ge\u00e4ndert werden.
 metasearch.addtemplate.dup.title=Maske vorhanden
 metasearch.addtemplate.dup.desc=Suchmaske %1 ist bereits installiert.
 metasearch.export.select.template.file=Maske speichern
 metasearch.import.select.template.file=Maske \u00f6ffnen
-v3.MainWindow.button.newtag.share=Neu! Tausche Torrent
-v3.buddies.faq=Mehr erfahren...
 dialog.uiswitch.title=Wechsel zur Vuze-Oberfl\u00e4che
 dialog.uiswitch.text=Dieses Merkmal ben\u00f6tigt die Vuze-Oberfl\u00e4che.\n\nVuze wird einen Neustart ben\u00f6tigen.
 dialog.uiswitch.button=Wechsel zur Vuze-Oberfl\u00e4che
@@ -2415,23 +2376,8 @@ azbuddy.tracker.enabled=Aktiviere 'Freund-Beschleunigung', um das Herunterladen
 azbuddy.protocolspeed=max. kB/s Freund-Protokolldaten
 v3.MainWindow.button.download=Herunterladen
 v3.MainWindow.button.run=Starte heruntergeladene Datei
-v3.activity.header.friend.requests.foryou=Freundanfragen - erhalten
-v3.activity.header.friend.requests.fromyou=Freundanfragen - gesendet
-v3.activity.header.friend.requests.accepted=Freundanfragen - akzeptiert
-v3.activity.header.share.requests=Tausche Torrentanfragen
-v3.activity.header.rating.reminders=Bewertungserinnerungen
-login.optional.message=Man muss eingeloggt sein, um dieses Merkmal zu nutzen.
-message.confirm.share.singular=Ausgezeichnet! Anfrage zum Tauschen wurde gesendet.
-message.confirm.share.plural=Ausgezeichnet! Anfragen zum Tauschen wurden gesendet.
-message.confirm.share.invite.singular=Ausgezeichnet! Anfrage zum Verbinden und Tauschen wurde gesendet.
-message.confirm.share.invite.plural=Ausgezeichnet! Anfragen zum Verbinden und Tauschen wurden gesendet.
-message.confirm.invite.singular=Ausgezeichnet! Freundanfrage wurden gesendet.
-message.confirm.invite.plural=Ausgezeichnet! Freundanfragen wurden gesendet.
-message.confirm.invite.error=Problem mit der Anfrage. Eine oder mehrere Einladungen hatten Fehler.
-message.prompt.add.friends=W\u00e4hle Freunde von der Seitenleiste (unten-links).
 message.taking.too.long=Es scheint, dass dies mehr Zeit ben\u00f6tigt, als erwartet.\n'ESC' dr\u00fccken, wenn diese Aktion abgebrochen werden soll.
 message.status.success=Erfolg
-message.intro.friends=Freunde hinzuf\u00fcgen.\nTorrents tauschen.\nSchneller herunterladen.
 azbuddy.tracker.bbb.status.title=Freund-Beschleunigung
 azbuddy.tracker.bbb.status.title.tooltip=Doppelklick f\u00fcr Details
 azbuddy.tracker.bbb.status.idle=Kein Beschleunigen
@@ -2440,13 +2386,8 @@ azbuddy.tracker.bbb.status.in=Man wird beschleunigt
 azbuddy.tracker.bbb.status.out=Beschleunigen von Freunden
 v3.MainWindow.search.go.tooltip=Suche ausf\u00fchren
 v3.MainWindow.search.last.tooltip=Zur\u00fcck zu den Suchergebnissen
-v3.activity.buddy-invited=Freundanfrage zu %1 gesendet.
-v3.activity.buddy-invited.multi=Freundanfragen zu folgenden Teilnehmern gesendet:\n%1
 metasearch.addtemplate.done.title=Maske hinzugef\u00fcgt
 metasearch.addtemplate.done.desc=Maske '%1' erfolgreich hinzugef\u00fcgt.\nSie wird bei der n\u00e4chsten Suche benutzt.
-v3.MainWindow.button.share=Tausche Inhalt
-v3.buddies.remove.buddy.dialog.title=Entfernen
-v3.buddies.remove.buddy.dialog.text=Wirklich %1 als Freund entfernen?
 ConfigView.section.security.nopw=Kein Passwort angegeben
 ConfigView.section.security.nopw_v=Kein Passwort verf\u00fcgbar, bitte in Vuze einloggen
 fileplugininstall.install.title=Plugin installieren?
@@ -2458,11 +2399,7 @@ azbuddy.os_away=Weg
 azbuddy.os_not_avail=Nicht erreichbar
 azbuddy.os_busy=Besch\u00e4ftigt
 azbuddy.ui.menu.disconnect=Trennen
-v3.chat.offline=%1 ist zur Zeit offline und wird die Nachricht erhalten, sobald sie/er wieder online ist.
-v3.chat.wrongversion=%1 benutzt eine Version von Vuze, die keinen Chat  unterst\u00fctzt.
 azbuddy.enable_chat_notif=Aktiviere Chat-Benachrichtigungen
-v3.buddies.dnd.info.dialog.text=Es wurde ein 'Drop Share' (Tauschen unter Freunden) eingeleitet.Der Inhalt wird zum Verteilen vorbereitet. Der Tauschbildschirm wird sich \u00f6ffnen, wenn der Inhalt bereit ist.\n\nVuze muss laufen gelassen werden, damit Freunde den Inhalt empfangen k\u00f6nnen.\nWeitere Informationen gibt es<A HREF="http://faq.vuze.com/?View=entry&EntryID=267">hier</A>.
-v3.buddies.dnd.info.dialog.remember=Zeige diese Nachricht nicht noch einmal
 progress.window.msg.progress=Bitte warten, bis die Aktion abgeschlossen ist
 DetailedListView.title=Detailierte Liste
 ConfigView.section.connection.network.max.outstanding.connect.attempts=Max. Anzahl ausstehender ausgehender Verbindungen
@@ -2510,24 +2447,17 @@ PluginDeprecation.view=Plugin-Debug
 PluginDeprecation.alert=Ein Plugin versuchte Funktionen zu nutzen, welche in Zukunft entfernt werden - bitte \u00f6ffne das Plugin-Debug-Log f\u00fcr weitere Informationen.
 TableColumn.header.Thumbnail=Symbol
 TableColumn.header.Thumbnail.info=Das Vorschaubild f\u00fcr Vuze-Inhalt; f\u00fcr andere Inhalte bietet das  Betriebssystem die Bilder.
-TableColumn.header.Rating_global=Bewertung
-TableColumn.header.Rating_global.info=Globale Bewertung dieses Inhaltes
 v3.MainWindow.menu.getting_started=&Beginnen
 MainWindow.menu.help.faq=H\u00e4ufige &Fragen (FAQ)
 MainWindow.menu.community.wiki=Community-&Wiki
 MainWindow.menu.community.forums=Community-Fo&ren
 MainWindow.menu.community.blog=Vuze-&Blog
-MainWindow.menu.community.add_friends=Freunde &hinzuf\u00fcgen
 MainWindow.menu.help.support=&Hilfe und Support
 externalLogin.title=Einloggen notwendig
 externalLogin.explanation=Die Maske "%1" ben\u00f6tigt es, eingeloggt zu sein. Dieses Fenster schliesst sich nach dem Einloggen automatisch. Falls nicht, bitte auf "Fertig" klicken.
 externalLogin.explanation.capture=Man muss eingeloggt sein, um diese Maske zu erstellen. Sobald dies geschehen ist, bitte auf "Fertig" klicken.
 Button.done=Fertig
 GeneralView.torrent_created_on_and_by=%1 mit %2
-v3.Share.wizard.title=Tauschen -- Assistent
-v3.AddFriends.header.message=F\u00fcge Freunde hinzu und tausche deine beliebtesten Torrents
-v3.AddFriends.header=Freunde hinzuf\u00fcgen
-v3.AddFriends.wizard.title=Hinzuf\u00fcgen von Freunden -- Assistent
 Button.continue=Weiter
 Button.preview=Vorschau
 Subscription.menu.forcecheck=Jetzt aktualisieren
@@ -2537,9 +2467,6 @@ sidebar.Library=Meine Bibliothek
 sidebar.LibraryDL=Unvollst\u00e4ndig
 sidebar.LibraryCD=Vollst\u00e4ndig
 authenticator.location=Ort
-v3.MainWindow.menu.publish.new=Neuen Inhalt ver\u00f6ffentlichen
-v3.MainWindow.menu.publish.mine=Eigene Ver\u00f6ffentlichungen
-v3.MainWindow.menu.publish.about=\u00dcber das Ver\u00f6ffentlichen
 v3.MainWindow.menu.showActionBarText=Zeige Text
 subscript.import.fail.title=Importierung fehlgeschlagen
 Subscription.menu.export=Exportieren
@@ -2586,7 +2513,6 @@ Wizard.Subscription.rss.subtitle3=Sobald neue Ergebnisse durch den RSS-Feed verf
 Wizard.Subscription.subscribe.library=Inhalt der Bibliothek
 Wizard.Subscription.subscribe.subscriptions=Relevante Abonnements
 Wizard.Subscription.subscribe.library.empty=Keine Abonnements verf\u00fcgbar?\n \nSuche das orangene Abonnementsymbol im Vuze-Netzwerk.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Weitere Informationen</A>
-TableColumn.header.videoLength=Videol\u00e4nge
 message.confirm.delete.title=L\u00f6schen best\u00e4tigen
 message.confirm.delete.text=Sicher, dass '%1' gel\u00f6scht werden soll?
 Subscription.menu.properties=Eigenschaften
@@ -2662,14 +2588,6 @@ azbuddy.ui.menu.cat.share=Aktiviere Abonnements mit Freunden
 azbuddy.ui.menu.cat.set=Kategorien eingeben
 azbuddy.ui.menu.cat.set_msg=Mit Komma getrennte Liste von Kategorien, oder alle mit 'All'
 azbuddy.ui.menu.cat_subs=Abonniere
-v3.buddy.prop.dn=Angezeigter Name
-v3.buddy.prop.un=Nutzername
-v3.buddy.prop.lupd=Letzte Aktualisierung
-v3.buddy.prop.pc=Ausstehende Nachrichten
-v3.buddy.prop.catout=Kategorien, die Freund abonnieren kann
-v3.buddy.prop.catin=Von Freund angebotene Kategorien
-v3.buddy.set.catout=Erlaube Freund Kategorieabonnement
-v3.buddy.set.catin=Abonniere Kategorie von Freund
 subs.prop.update_period=Aktualisierungsperiode
 azbuddy.enable_cat_pub=\u00d6ffentliche Kategorien, die ALLE Freunde abonnieren k\u00f6nnen (getrennt durch Komma)
 v3.dialog.cnclose.title=%1 geschlossen
@@ -2685,12 +2603,9 @@ TableColumn.header.category.info=Name der Kategorie des Torrents
 TableColumn.header.DateCompleted.info=Zeitpunkt der Vervollst\u00e4ndigung des Downloads
 TableColumn.header.AzProduct.info=Ursprungsnetzwerk des Torrents
 TableColumn.header.health.info=Fitness der Verbindung zum Torrentschwarm
-TableColumn.header.Info.info=Knopf, um Details des Inhaltes zu sehen
 TableColumn.header.maxuploads.info=Maximale Anzahl von Quellen, zu denen gleichzeitig hochgeladen wird
 TableColumn.header.name.info=Name des Torrents
 TableColumn.header.unopened.info=Symbol, das zeigt, ob Torrent abgespielt (ge\u00f6ffnet) wurde
-TableColumn.header.Quality.info=Qualit\u00e4t des Inhaltes (HD, SD)
-TableColumn.header.RateIt.info=F\u00e4higkeit, um Inhalt zu bewerten
 TableColumn.header.savepath.info=Zielverzeichnis oder -datei der Torrentdaten
 TableColumn.header.SeedingRank.info=Wert, der die Dringlichkeit f\u00fcr Upload anzeigt. Je h\u00f6her der Wert, desto gr\u00f6\u00dfer der Bedarf.
 TableColumn.header.shareRatio.info=Verh\u00e4lnis von hochgeladener zu heruntergeladener Datenmenge
@@ -2700,7 +2615,6 @@ TableColumn.header.upspeed.info=Aktuelle Uploadgeschwindigkeit
 TableColumn.header.downspeed.info=Aktuelle Downloadgeschwindigkeit
 TableColumn.header.up.info=Aktuelle hochgeladene Datenmenge
 TableColumn.header.down.info=Datenmenge, die bis jetzt von anderen Nutzer erhalten wurde
-TableColumn.header.videoLength.info=Spielzeit von Vuze-Videoinhalten
 TableColumn.header.ProgressETA.info=Kombiniert Status, Vervollst\u00e4ndigung, ETA und Downloadgeschwindigkeit in einer Spalte
 TableColumn.header.eta.info=Gesch\u00e4tzte Zeit bis zur Vervollst\u00e4ndigung des Downloads
 Pieces.column.#.info=Teilnummer
@@ -2852,9 +2766,11 @@ subscriptions.config.autostart.max=Nur starten, wenn <= MB [0: unbegrenzt]
 dlg.corewait.title=Initialisiere Kern
 dlg.corewait.text=Einen Augenblick bitte...\n\nDie Anfrage wird bearbeitet, sobald Vuze die Initialisierung abgeschlossen hat
 library.core.wait=Einen Augenblick bitte...\nVuze wird initialisiert
+ConfigView.label.StartUIBeforeCore=Starte Oberfl\u00e4che vor Kerninitialisierung
 general.add.friends=F\u00fcge Freunde hinzu!
 general.all.friends=Alle Freunde
 friend.mod.subs=Rechtsklick, um das Abonnement zu \u00e4ndern
+TableColumn.header.class=Klasse
 device.rss.group=Lokaler RSS-Feed
 devices.xcode.rsspub=Ver\u00f6ffentliche RSS-Feed
 device.rss.enable=Erzeuge RSS-Feed von umgewandeltem Inhalt - macht den Inhalt f\u00fcr RSS-Feed-Betrachter verf\u00fcgbar
@@ -2873,6 +2789,7 @@ devices.xcode.mancopy=Kopiere Dateien manuell
 devices.xcode.show.cat=Nach Kategorie trennen
 ConfigView.label.alwaysShowLibraryHeader=Zeige immer Tabellenbezeichnung in Bibliothek (Meine Torrents)
 devices.cat.show=Zeige Kategorien
+devices.tivo.machine=TiVo-Ger\u00e4tename
 devices.info.copypending=%1 Datei(en) wartet/warten auf Kopiervorgang
 device.error.xcodefail=Umwandlung fehlgeschlagen
 device.error.copyfail=Dateien konnten nicht in das Zielverzeichnis kopiert werden
@@ -2882,3 +2799,67 @@ device.error.copytonowrite='Zielverzeichnis' "%1" nicht schreibbar
 device.error.copyfail2=Dateien konnten nicht auf das Zielger\u00e4t kopiert werden
 v3.deviceview.infobar.line2.psp=Videos werden auf die PSP kopiert, wenn diese verbunden ist.
 devices.info.copypending2=%1 Datei(en) wartet/warten auf Kopiervorgang. Bitte Ger\u00e4t verbinden.
+subscriptions.column.nb-subscribers=Abonnementen
+device.offlinedownloader.view.title=
+device.od.enable=Aktiviere Offline-Download-Ger\u00e4te
+device.odauto.enable=Verwalte Downloads automatisch
+device.odpt.enable=Private Torrents einschliessen
+devices.contextmenu.od=Offline-Downloading
+devices.contextmenu.od.auto=<Automatisch>
+devices.contextmenu.od.enable=Aktivieren
+devices.contextmenu.od.enabled=Aktiviert
+devices.od.view.heading=Downloads f\u00fcr Offline-Downloading eingeplant
+DevicesOD.column.od_completion=\u00dcbertragungsfortschritt
+device.od.turnon.title=Aktiviere Offline-Downloader-Unterst\u00fctzung
+device.is.disabled=Ger\u00e4te ist deaktiviert
+device.configure=Konfigurieren...
+device.od.error.notfound=Ger\u00e4t scheinbar ausgeschaltet
+device.od.error.opfailstatus=Ger\u00e4tefehler bei Befehl %1: Status %2
+device.od.error.opfailexcep=Ger\u00e4tefehler bei Befehl %1: Ausnahme %2
+device.od.error.nospace=Kein Speicherplatz auf Ger\u00e4t verf\u00fcgbar oder kein externes Laufwerk verbunden
+device.od.space=Verf\u00fcgbarer Speicherplatz
+ConfigView.section.style.forceSIValues=Zeige Zahlen als IEC-Werte entgegen der angezeigten Einheit (z.B. 1MB = 1MiB = 1048576B)
+ConfigView.label.enableSystrayToolTip=Zeige Download-Statistiken auf Hover
+devices.activation=Ger\u00e4teaktivierung
+button.nothanks=Nein danke
+devices.od.turnon.text1=Es wurde erkannt, dass eine Verbindung mit %1 besteht.
+devices.od.turnon.text2=Soll %1 das Herunterladen der Dateien fortsetzen, wenn der Computer offline ist?
+devices.od.turnon.text3=Bitte eine Festplatte mit %1 verbinden, damit dieses Merkmal aktiviert werden kann.
+devices.od.turnon.learn=Mehr erfahren >
+devices.router=Router
+devices.od=Offline-Downloader
+webui.pairingenable=Aktiviere Paarung
+webui.group.access=Zugiffskontrolle
+ConfigView.section.Pairing=Paarung
+pairing.accesscode=Zugangscode
+pairing.ac.getnew=Teile neuen Zugangscode zu
+pairing.ac.getnew.create=Erstellen
+pairing.host=Hostadresse (DNS-Name)
+pairing.group.explicit=Ausf\u00fchrliche Attribute
+pairing.explicit.enable=Aktivieren
+pairing.explicit.info=Normalerweise m\u00fcssen ausf\u00fchrliche IP-Attribute nicht angegeben werden, da diese automatisch abgeleitet werden k\u00f6nnen.\nDas 'host'-Attribut kann benutzt werden, falls ein DynDNS-Konto und die zugeh\u00f6rige Software vorhanden sind, um die dynamische IP korrekt zu registrieren.
+pairing.op.fail=Paarung fehlgeschlagen
+pairing.alloc.fail=Zuteilung von Zugangscode fehlgeschlagen\n%1
+pairing.enable=Aktiviere Paarung von Vuze und entfernten Anwendungen / Oberfl\u00e4chen
+pairing.status.registered=Aktualisierung erfolgreich (%1)
+pairing.status.pending=Aktualisierung erfolgt um %1
+pairing.status.initialising=Initialisieren
+pairing.status.disabled=Deaktiviert
+pairing.view.registered=Anklicken, um aktuelle Registrierungsdetails zu sehen
+webui.pairing.info.n=Paarung deaktiviert. Weitere Informationen unter Verbindung -> Paarung.
+webui.pairing.info.y=Paarung aktiviert. Weitere Informationen unter Verbindung -> Paarung.
+webui.enable=Aktivieren (*)
+ConfigView.section.rss=Lokales RSS
+subscriptions.rss.enable=Erstelle RSS-Feeds von Abos
+device.tivo.enable=Aktiviere TiVo-Unterst\u00fctzung
+Button.removeAll=Alle entfernen
+label.rename=Bennen %1 um
+RCM.column.rc_rank=Rang
+RCM.column.rc_created=Erstellt
+RCM.column.rc_lastseen=Zuletzt gesehen
+RCM.column.rc_level=Stufe
+rcm.view.heading=Schwarmentdeckungen
+rcm.config.enabled=Aktivieren
+rcm.config.max_results=Maximale Ergebnisse
+rcm.config.max_level=Maximale Stufe
+rcm.search.provider=Schwarm
diff --git a/org/gudy/azureus2/internat/MessagesBundle_fi_FI.properties b/org/gudy/azureus2/internat/MessagesBundle_fi_FI.properties
index 8d78187..ad3034b 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_fi_FI.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_fi_FI.properties
@@ -228,7 +228,7 @@ GeneralView.label.totalspeed.tooltip=Kaikkien yhdistettyjen k\u00e4ytt\u00e4jien
 GeneralView.label.averagespeed=keskim\u00e4\u00e4rin
 GeneralView.label.filename=Nimi: 
 GeneralView.label.totalsize=Koko yhteens\u00e4: 
-GeneralView.label.savein=Tallennuskohde: 
+GeneralView.label.savein=Tallennushakemisto: 
 GeneralView.label.hash=Tiiviste: 
 GeneralView.label.numberofpieces=Osien m\u00e4\u00e4r\u00e4: 
 GeneralView.label.size=Osan koko: 
@@ -598,8 +598,8 @@ ConfigView.section.style.reOrderDelay=J\u00e4rjest\u00e4 taulukot uudelleen n\u0
 ConfigView.section.style.reOrderDelay.never=Ei koskaan
 ConfigView.section.logging=Loki
 ConfigView.section.logging.enable=Kirjaa tapahtumat lokitiedostoon
-ConfigView.section.logging.logdir=Tallennushakemisto
-ConfigView.section.logging.choosedefaultsavepath=Valitse tallennushakemisto
+ConfigView.section.logging.logdir=Lokien tallennushakemisto
+ConfigView.section.logging.choosedefaultsavepath=Valitse lokien tallennushakemisto
 GeneralView.label.updatein.querying=Pyydet\u00e4\u00e4n tietoja...
 configureWizard.nat.sharePort=K\u00e4yt\u00e4 yht\u00e4 porttia kaikkien torrent-tiedostojen sis\u00e4\u00e4ntulevalle liikenteelle
 ConfigView.section.logging.maxsize=Tiedoston enimm\u00e4iskoko
@@ -733,7 +733,6 @@ ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Siirrot-ikkunan sis\u00
 #
 #2.0.7.0
 #
-ConfigView.section.style.verticaloffset=Nosta grafiikkaa yhdell\u00e4 rivill\u00e4 yl\u00f6sp\u00e4in (GTK-korjaus)
 security.certtruster.title=Turvallisuusvarmennevaroitus
 security.certtruster.intro=Turvallisuusvarmenteen my\u00f6nsi osapuoli, johon et luota.
 security.certtruster.resource=L\u00e4hde:
@@ -882,13 +881,13 @@ TableColumn.header.availability.info=T\u00e4ysien kopioiden lukum\u00e4\u00e4r\u
 TableColumn.header.availability=Saatavuus
 TableColumn.header.category=Luokka
 MyTorrentsView.header=Keskener\u00e4iset torrent-tiedostot
-TableColumn.header.maxuploads=L\u00e4h.paikat
+TableColumn.header.maxuploads=L\u00e4hetyspaikat
 MyTorrentsView.menu.category.delete=&Poista luokka
 MyTorrentsView.menu.forceStart=K\u00e4ynnist\u00e4 (&ohita s\u00e4\u00e4nn\u00f6t)
 MyTorrentsView.menu.queue=&K\u00e4ynnist\u00e4 (aseta jonoon)
 MyTorrentsView.menu.setCategory.add=&Lis\u00e4\u00e4 luokka...
 MyTorrentsView.menu.setCategory=Aseta &luokka
-TableColumn.header.savepath=Tallennuskohde
+TableColumn.header.savepath=Tallennushakemisto
 TableColumn.header.SeedingRank=L\u00e4hetystarve
 TableColumn.header.totalspeed.info=Yhdistettyin\u00e4 olevien k\u00e4ytt\u00e4jien siirtonopeus yhteens\u00e4.
 TableColumn.header.totalspeed=Nopeus yht.
@@ -1068,7 +1067,7 @@ UpdateWindow.cancel=Peruuta
 UpdateWindow.quit=Lopeta
 UpdateWindow.close=Sulje
 UpdateWindow.ok=P\u00e4ivit\u00e4
-UpdateWindow.restart=K\u00e4ynnist\u00e4 uudelleen
+UpdateWindow.restart=K\u00e4ynnist\u00e4 Vuze uudelleen
 UpdateWindow.status.downloading=Ladataan
 UpdateWindow.status.done=Valmis
 UpdateWindow.status.failed=P\u00e4ivitys ep\u00e4onnistui
@@ -1226,7 +1225,7 @@ CacheView.reads.hits=k\u00e4ytt\u00f6
 CacheView.writes.title=Siirr\u00e4nt\u00e4kirjoitukset
 CacheView.writes.toCache=V\u00e4limuistiin
 CacheView.writes.toFile=Tiedostoon
-CacheView.writes.hits=tallennettu
+CacheView.writes.hits=s\u00e4\u00e4stetty
 CacheView.speeds.title=Luku- ja kirjoitusnopeudet
 CacheView.speeds.reads=Luvut
 CacheView.speeds.writes=Kirjoitukset
@@ -1311,6 +1310,7 @@ wizard.maketorrents.autoopen=Kun torrent-tiedosto on luotu, avaa se suoraan l\u0
 ConfigView.section.sharing.rescanenable=Tarkasta jaetut kohteet s\u00e4\u00e4nn\u00f6llisesti muutosten varalta
 ConfigView.section.sharing.rescanperiod=Tarkastusten aikav\u00e4li (sekunneissa)
 ConfigView.section.connection.advanced=Lis\u00e4asetukset
+ConfigView.section.connection.advanced.url=http://wiki.vuze.com/index.php/UG_Options#Advanced_Network_Settings
 ConfigView.section.connection.advanced.mtu=Pakettien enimm\u00e4iskoko (MTU)
 ConfigView.section.connection.advanced.mtu.tooltip=MTU-arvolla s\u00e4\u00e4dell\u00e4\u00e4n paketin enimm\u00e4iskokoa, joka voidaan siirt\u00e4\u00e4 yhdess\u00e4 kehyksess\u00e4.\nVuze v\u00e4hent\u00e4\u00e4 itse MTU-arvosta aina 40 tavua, jolloin saadaan MSS-arvo (paketin sis\u00e4lt\u00e4m\u00e4 varsinainen tieto ilman otsikkotietoja).\nEsimerkkej\u00e4 suositelluista MTU-arvoista:\n  576 - soittoyhteydet\n1492 - PPPoE:t\u00e4 k\u00e4ytt\u00e4v\u00e4t laajakaistayhteydet\n1500 - Ethernet-l\u00e4hiverkko, DSL- ja kaapelimodeemilaajakaistayhteydet
 ConfigView.section.connection.advanced.SO_RCVBUF=Pistokkeen SO_RCVBUF-koko (0 = k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n oletusarvo)
@@ -1330,7 +1330,7 @@ ConfigView.section.interface.display.add_torrents_silently=Avaa torrent-tiedosto
 ConfigView.section.interface.display.add_torrents_silently.tooltip=Jos Vuze on pienennettyn\u00e4 esimerkiksi ilmoitusalueelle,\nei Vuze avaudu ruudulle torrent-tiedostoa avattaessa.
 TableColumn.header.maxdownspeed=Enim.lat.nopeus
 TableColumn.header.maxdownspeed.info=Torrent-tiedoston enimm\u00e4islatausnopeus.
-PeersGraphicView.title=K\u00e4ytt\u00e4j\u00e4t
+PeersGraphicView.title=Parvi
 ConfigView.section.tracker.passwordwebhttpsonly=Salli p\u00e4\u00e4sy sivustolle vain HTTPS-protokollaa k\u00e4ytt\u00e4en
 TableColumn.header.torrentpath=Torrent-tiedosto
 TableColumn.header.torrentpath.info=Torrent-tiedoston sijainti ja nimi
@@ -1383,8 +1383,8 @@ Button.abort=Keskeyt\u00e4
 ConfigView.section.ipfilter.enablebanning=Est\u00e4 k\u00e4ytt\u00e4j\u00e4t, jotka l\u00e4hett\u00e4v\u00e4t korruptoitunutta tietoa toistuvasti
 Network.alert.acceptfail=Portin %1 (%2) k\u00e4yt\u00f6ss\u00e4 esiintyi ongelmia toistuvasti - toiminta lopetettu. Tarkasta palomuurin asetukset portin osalta niin, ett\u00e4 sis\u00e4\u00e4ntulevat yhteydet p\u00e4\u00e4sev\u00e4t l\u00e4pi.
 MyShares.column.category=Luokka
-UpdateWindow.restartLater=K\u00e4yn. uud. my\u00f6h.
-MainWindow.menu.file.restart=&K\u00e4ynnist\u00e4 uudelleen
+UpdateWindow.restartLater=K\u00e4yn. uud. my\u00f6hemmin
+MainWindow.menu.file.restart=&K\u00e4ynnist\u00e4 Vuze uudelleen
 MainWindow.dialog.restartconfirmation.title=K\u00e4ynnist\u00e4 Vuze uudelleen
 MainWindow.dialog.restartconfirmation.text=Haluatko varmasti k\u00e4ynnist\u00e4\u00e4 Vuzen uudelleen?
 deletetorrent.message1=Olet aikeissa poistaa seuraavan siirron torrent-tiedoston:\n
@@ -1782,9 +1782,9 @@ Button.markSelected=Merkitse valitut
 Button.unmarkSelected=Poista merkinn\u00e4t valituista
 plugins.basicview.config=Asetukset
 TorrentOptionsView.param.max.uploads=L\u00e4hetyspaikkojen enimm\u00e4ism\u00e4\u00e4r\u00e4 (v\u00e4hint\u00e4\u00e4n 2)
-MyTorrentsView.dialog.setPosition.title=Sijoita uudelleen
-MyTorrentsView.dialog.setPosition.text=Anna j\u00e4rjestysnumero, jonka kohdalle tahdot siirt\u00e4\u00e4 valitut torrent-tiedostot:
-MyTorrentsView.menu.reposition.manual=Sijoita uudelleen...
+MyTorrentsView.dialog.setPosition.title=Vaihda paikkaa jonossa
+MyTorrentsView.dialog.setPosition.text=Anna uusi j\u00e4rjestysnumero valitulle torrent-tiedostolle:
+MyTorrentsView.menu.reposition.manual=Vaihda paikkaa jonossa...
 ConfigView.section.connection.advanced.info.link=Katso lis\u00e4tietoja t\u00e4st\u00e4
 ConfigView.section.connection.advanced.socket.group=Pistokeasetukset
 ConfigView.section.connection.advanced.bind_port=Sido paikalliseen porttiin (0 = ei k\u00e4yt\u00f6ss\u00e4)
@@ -1905,7 +1905,7 @@ ConfigView.section.file.defaultdir.bestguess=K\u00e4yt\u00e4 parasta arvausta va
 ConfigView.section.file.defaultdir.ask=Hakemisto:
 ConfigView.section.file.defaultdir.lastused=P\u00e4ivit\u00e4 oletustallennushakemistoksi sijainti, jonne on viimeksi tallennettu
 ConfigView.section.file.config.section=Asetustiedostot
-ConfigView.section.file.config.currentdir=Tallennushakemisto:
+ConfigView.section.file.config.currentdir=Asetusten tallennushakemisto:
 ConfigView.section.torrent.decoding=Merkist\u00f6jen purkaminen
 ConfigView.section.logging.udptransport=J\u00e4ljit\u00e4 yksityiskohtaiset UDP-siirtojen tiedot
 Tracker.announce.ignorePeerSeed=Ohitetaan lataajien/l\u00e4hteiden m\u00e4\u00e4r\u00e4. %1
@@ -1937,16 +1937,14 @@ ConfigView.section.connection.tcp.enable=K\u00e4yt\u00e4 TCP:t\u00e4
 ConfigView.section.connection.udp.enable=K\u00e4yt\u00e4 UDP:t\u00e4
 ConfigView.section.style.showiconbar=N\u00e4yt\u00e4 ty\u00f6kalupalkki
 MainWindow.menu.view.iconbar=Ty\u00f6kalupalkki
-MyTorrentsView.menu.rename=Nime\u00e4 uudelleen
-MyTorrentsView.menu.rename.displayed=N\u00e4ytett\u00e4v\u00e4 nimi
-MyTorrentsView.menu.rename.save_path=Tallennuskohde
-MyTorrentsView.menu.rename.displayed_and_save_path=Molemmat
-MyTorrentsView.menu.rename.displayed.enter.title=Uudelleennime\u00e4 n\u00e4ytett\u00e4v\u00e4 nimi
-MyTorrentsView.menu.rename.displayed.enter.message=Anna uusi n\u00e4ytett\u00e4v\u00e4 nimi t\u00e4lle kohteelle.\nJos et kirjoita mit\u00e4\u00e4n, k\u00e4ytet\u00e4\u00e4n alkuper\u00e4ist\u00e4 nime\u00e4.
-MyTorrentsView.menu.rename.save_path.enter.title=Uudelleennime\u00e4 tallennuskohde
-MyTorrentsView.menu.rename.save_path.enter.message=Anna uusi tallennusnimi t\u00e4lle kohteelle.\nJos et kirjoita mit\u00e4\u00e4n, tallennusnimen\u00e4 k\u00e4ytet\u00e4\u00e4n\nn\u00e4ytett\u00e4v\u00e4\u00e4 nime\u00e4.
-MyTorrentsView.menu.rename.displayed_and_save_path.enter.title=Uudelleennime\u00e4 kohde
-MyTorrentsView.menu.rename.displayed_and_save_path.enter.message=Anna uusi nimi t\u00e4lle kohteelle.\nJos et kirjoita mit\u00e4\u00e4n, k\u00e4ytet\u00e4\u00e4n alkuper\u00e4isi\u00e4 nimi\u00e4.
+MyTorrentsView.menu.rename=Nime\u00e4 uudelleen...
+MyTorrentsView.menu.rename.displayed=Vaihda n\u00e4ytett\u00e4v\u00e4 nimi
+MyTorrentsView.menu.rename.save_path=Tallennushakemisto
+AdvRenameWindow.title=Uudelleennime\u00e4 torrent-lataus
+AdvRenameWindow.message=Anna uusi nimi ja valitse nimett\u00e4v\u00e4t kohteet:
+AdvRenameWindow.rename.torrent=Torrent-tiedosto
+MyTorrentsView.menu.rename.displayed.enter.title=Vaihda torrentin nimi
+MyTorrentsView.menu.rename.displayed.enter.message=Anna uusi nimi t\u00e4lle torrentille.
 MyTorrentsView.menu.edit_comment=Muokkaa kommenttia
 MyTorrentsView.menu.edit_comment.enter.title=Muokkaa kommenttia
 MyTorrentsView.menu.edit_comment.enter.message=Anna oma kommentti siirrolle:
@@ -2159,17 +2157,23 @@ v3.MainWindow.button.comment=Kommentoi
 v3.MainWindow.button.viewdetails=Lis\u00e4tiedot
 v3.MainWindow.button.play=Toista
 v3.MainWindow.button.cancel=Peruuta
-v3.MainWindow.button.sendtofriend=Jaa torrent
 v3.MainWindow.button.preview=Esikatselu
 v3.MainWindow.view.wait=Alustetaan n\u00e4kym\u00e4\u00e4, odota hetki.
 v3.MainWindow.xofx=%1/%2
 v3.MainWindow.Loading=Ladataan, odota hetki.
 v3.filter-bar=Nimisuodatus:
-v3.MainWindow.search.defaultText=Hae Vuze sta
+v3.MainWindow.search.defaultText=Etsi...
 v3.mb.delPublished.title=L\u00e4hett\u00e4misen lopettaminen
 v3.mb.delPublished.text=Huom.! T\u00e4m\u00e4 toiminto ei poista julkaisemaasi sis\u00e4lt\u00f6\u00e4 ('%1') <A HREF="%2">%3-sivustolta</A>.\n\nValitse Tuhoa vain, jos haluat j\u00e4tt\u00e4\u00e4 julkaisusi kaikkien n\u00e4ht\u00e4v\u00e4ksi ja ladattavaksi, mutta vapauttaa omia resurssejasi. Varmista kuitenkin ensin, ett\u00e4 julkaisu on siirretty kokonaan muiden saataville (<A HREF="%4">kuinka?</A>).\n\nValitse Peruuta, jos aikomuksenasi on poistaa julkaisemasi sis\u00e4lt\u00f6 kokonaan %3-sivustolta. Voit tehd\u00e4 t\u00e4m\u00e4n Julkaise-v\u00e4lilehdelt\u00e4, Published Content -sivulta valitsemalla X-painikkeen haluamasi kohteen vierelt\u00e4.\n\nKatso lis\u00e4tietoja <A HREF="%4">t\u00e4st\u00e4</A>.\n\n
 v3.mb.delPublished.delete=&Tuhoa
 v3.mb.delPublished.cancel=&Peruuta
+v3.mb.openFile.title=Avaa tiedosto
+v3.mb.openFile.text.known=Vuze Player ei t\u00e4ll\u00e4 hetkell\u00e4 tue t\u00e4t\u00e4 sis\u00e4lt\u00f6\u00e4. Lue k\u00e4ytt\u00e4j\u00e4yhteis\u00f6n laatima Soitto-opas\n <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Playback Guide</a> saadaksesi lis\u00e4tietoja.\n\nTiedoston tyyppi voi olla: %2 (%3)\n
+v3.mb.openFile.text.unknown=Vuze Player ei t\u00e4ll\u00e4 hetkell\u00e4 tue t\u00e4t\u00e4 sis\u00e4lt\u00f6\u00e4. Lue k\u00e4ytt\u00e4j\u00e4yhteis\u00f6n laatima Soitto-opas\n <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Playback Guide</a> saadaksesi lis\u00e4tietoja.\n\nTiedostotyyppi: %2\n
+v3.mb.openFile.button.play=Soita
+v3.mb.openFile.button.cancel=Keskeyt\u00e4
+v3.mb.openFile.button.guide=Lue soitto-opas
+v3.mb.openFile.remember=Avaa tiedostot aina kysym\u00e4tt\u00e4 minulta
 v3.mb.PlayFileNotFound.title=Tiedostoa ei l\u00f6ytynyt
 v3.mb.PlayFileNotFound.text=Kohteen '%1' tiedostoja ei l\u00f6ytynyt
 v3.mb.PlayFileNotFound.button.remove=Poista Vuzesta
@@ -2347,8 +2351,8 @@ plugin.install.class_version_error=T\u00e4m\u00e4 lis\u00e4osa vaatii toimiaksee
 v3.MainWindow.tab.minilibrary=Lataukset
 v3.MainWindow.tab.events=Tapahtumat
 button.columnsetup.tooltip=Valitse n\u00e4ytett\u00e4v\u00e4t sarakkeet
-v3.activity.remove.title=Poista tapahtumamerkint\u00e4
-v3.activity.remove.text=Haluatko varmasti poistaa tapahtumamerkinn\u00e4n '%1'?
+v3.activity.remove.title=Poista viesti
+v3.activity.remove.text=Haluatko varmasti poistaa t\u00e4m\u00e4n viestin?\n%1
 #v3.MainWindow.menu.view.configuration=Preferences
 #v3.MainWindow.menu.view.configuration.keybinding=Meta+,
 v3.MainWindow.menu.file.closewindow=Sulje
@@ -2364,7 +2368,7 @@ ConfigView.section.style.usePathFinder=K\u00e4yt\u00e4 Path Finderia Finderin si
 menu.sortByColumn=Lajittele sarakkeen '%1' mukaan
 MyTorrentsView.menu.manual.per_peer=Manuaalinen (k\u00e4ytt\u00e4j\u00e4kohtainen)...
 MyTorrentsView.menu.manual.shared_peers=Manuaalinen (jaettuna valittujen kesken)...
-v3.button.removeActivityEntry=Poista tapahtumamerkint\u00e4
+v3.button.removeActivityEntry=Poista viesti
 v3.splash.initSkin=Alustetaan k\u00e4ytt\u00f6liittym\u00e4olemusta
 v3.splash.hookPluginUI=Liitet\u00e4\u00e4n lis\u00e4osak\u00e4ytt\u00f6liittym\u00e4
 OpenTorrentWindow.mb.notTorrent.cannot.display=Tietoja ei voida n\u00e4ytt\u00e4\u00e4 kunnolla
@@ -2425,10 +2429,17 @@ Button.bar.share=Jaa
 Button.bar.add=Lis\u00e4\u00e4
 Button.bar.edit=Editoi
 Button.bar.edit.cancel=Editointi valmis
-ConfigView.section.security.vuze.login=Sinun t\u00e4ytyy olla kirjautuneena Vuzeen voidaksesi suorittaa t\u00e4m\u00e4n toiminnon
+v3.MainWindow.menu.view.pluginbar=Lis\u00e4osat-palkki
 MainWindow.dialog.select.vuze.file=Valitse Vuze-tiedosto
 MainWindow.menu.file.open.vuze=Vuze-tiedosto...
-v3.MainWindow.button.newtag.share=Uusi! Jaa torrent
+metasearch.addtemplate.title=Asenna hakupohja?
+metasearch.addtemplate.desc=Oletko varma, ett\u00e4 haluat asentaa hakupohjan nimelt\u00e4\u00e4n '%1'?
+v3.share.private.title=Torrentin jakaminen
+v3.share.private.text=Valittu torrent on merkitty yksityiseksi (Private Torrent).\n\nEt voi jakaa yksityisi\u00e4 torrentteja.
+metasearch.addtemplate.dup.title=Duplikaatti hakupohja
+metasearch.addtemplate.dup.desc=Hakupohja %1 on jo asennettu
+metasearch.export.select.template.file=Tallenna hakupohja
+metasearch.import.select.template.file=Avaa hakupohja
 dialog.uiswitch.title=Vaihda Vuze-k\u00e4ytt\u00f6liittym\u00e4\u00e4n
 dialog.uiswitch.text=T\u00e4t\u00e4 toimintoa voi k\u00e4ytt\u00e4\u00e4 vain Vuze-k\u00e4ytt\u00f6liittym\u00e4ss\u00e4.\n\nVuzen pit\u00e4\u00e4 uudelleenk\u00e4ynnisty\u00e4.
 dialog.uiswitch.button=Vaihda Vuze-k\u00e4ytt\u00f6liittym\u00e4\u00e4n
@@ -2436,10 +2447,12 @@ v3.MainWindow.button.download=Lataa
 v3.MainWindow.button.run=K\u00e4ynnist\u00e4 ladattu tiedosto
 v3.activity.header.downloads=Lataukset
 v3.activity.header.vuze.news=Vuze-uutiset
-login.optional.message=Sinun pit\u00e4\u00e4 olla kirjautunut k\u00e4ytt\u00e4\u00e4kseni t\u00e4t\u00e4 toimintoa
 message.taking.too.long=Toiminto n\u00e4ytt\u00e4\u00e4 kest\u00e4v\u00e4n odotettua pidemp\u00e4\u00e4n.\nPaina 'ESC', jos haluat keskeytt\u00e4\u00e4 operaation
 message.status.success=Onnistui
-v3.MainWindow.button.share=Jaa sis\u00e4lt\u00f6\u00e4
+v3.MainWindow.search.go.tooltip=Suorita haku
+v3.MainWindow.search.last.tooltip=Palaa hakutuloksiin
+metasearch.addtemplate.done.title=Hakupohja lis\u00e4tty
+metasearch.addtemplate.done.desc=Hakupohja '%1' lis\u00e4tty onnistuneesti.\nSit\u00e4 k\u00e4ytet\u00e4\u00e4n jo seuraavaan hakuusi!
 ConfigView.section.security.nopw=Salasana ei ollut annettu
 ConfigView.section.security.nopw_v=Salasana ei tiedossa, kirjaudu sis\u00e4\u00e4n Vuzeen
 fileplugininstall.install.title=Asenna lis\u00e4osa?
@@ -2476,14 +2489,11 @@ PluginDeprecation.view=Lis\u00e4osien Debug
 PluginDeprecation.alert=Lis\u00e4osa on yritt\u00e4nyt k\u00e4ytt\u00e4\u00e4 toimintoa, joka tullaan poistamaan tulevaisuudessa. Katso lis\u00e4tietoja lis\u00e4osien debug-lokista.
 TableColumn.header.Thumbnail=Kuvake
 TableColumn.header.Thumbnail.info=Kuvake, joka riippuu sis\u00e4ll\u00f6n tyypist\u00e4. Vuze asettaa sen omalle sis\u00e4ll\u00f6lleen, muutoin se tulee k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4st\u00e4.
-TableColumn.header.Rating_global=Arvostelu
-TableColumn.header.Rating_global.info=Globaali arvostelu sis\u00e4ll\u00f6lle
 v3.MainWindow.menu.getting_started=Aloitussivu
 MainWindow.menu.community=&K\u00e4ytt\u00e4j\u00e4yhteis\u00f6
 MainWindow.menu.help.faq=&FAQ (UKK)
 MainWindow.menu.community.wiki=K\u00e4ytt\u00e4jien Wiki-artikkelit
 MainWindow.menu.community.forums=K\u00e4ytt\u00e4jien keskustelufoorumi
-MainWindow.menu.community.add_friends=Lis\u00e4\u00e4 yst\u00e4vi\u00e4
 MainWindow.menu.help.support=Apua ja tukea
 Button.done=Valmis
 GeneralView.torrent_created_on_and_by=%1 / %2
@@ -2494,9 +2504,7 @@ sidebar.LibraryDL=Lataukset
 sidebar.LibraryCD=Valmiit
 authenticator.location=Sijainti
 authenticator.details=Detaljit
-v3.MainWindow.menu.publish.new=Julkaise uutta sis\u00e4lt\u00f6\u00e4
-v3.MainWindow.menu.publish.mine=Sinun julkaisemasi sis\u00e4lt\u00f6
-v3.MainWindow.menu.publish.about=Sis\u00e4ll\u00f6n julkaisemisesta...
+v3.MainWindow.menu.showActionBarText=N\u00e4yt\u00e4 teksti
 Button.remove=Poista
 Button.send=L\u00e4het\u00e4
 Button.back=Takaisin
@@ -2504,26 +2512,31 @@ sidebar.LibraryUnopened=Ei-katsotut
 TableColumn.header.unopened=Uusi
 Unopened.bigView.header=Uusi
 ConfigView.section.Subscriptions=Tilaukset
+v3.activity.button.readall=Merkitse kaikki luetuiksi
 ConfigView.interface.start.library=K\u00e4ynnist\u00e4 Kirjastossa
 TableColumn.header.activityNew=Uusi
 TableColumn.header.activityType=Tyyppi
 TableColumn.header.activityText=Viesti
 TableColumn.header.activityDate=Lis\u00e4ysp\u00e4iv\u00e4
 TableColumn.header.activityActions=Toimet
+Search.menu.engines=Hakupohjat
 #what you've watched? Discover more with a single click...
 Button.search=Etsi
 Button.save=Tallenna
 Button.add=Lis\u00e4\u00e4
-TableColumn.header.videoLength=Videon pituus
 message.confirm.delete.title=Vahvista poistaminen
 message.confirm.delete.text=Haluatko varmasti poistaa '%1'?
 props.window.title='%1':n ominaisuudet
 externalLogin.wait=Sivu lautautuu, odota...
 TableColumn.menu.date_added.time=N\u00e4yt\u00e4/piilota lis\u00e4ysaika
 subscriptions.view.title=Tilaukset
+metasearch.template.version.bad=Hakupohjan '%1' asentaminen vaati Vuzen p\u00e4ivitt\u00e4misen
+metasearch.addtemplate.failed.title=Asennus ep\u00e4onnistui
+metasearch.addtemplate.failed.desc=Hakupohjan asennus ep\u00e4onnistui: %1
 statusbar.feedback=Anna palautetta
 statusbar.feedback.tooltip=Paina t\u00e4st\u00e4 antaaksesi palautetta
 sidebar.Activity=Tiedotteet
+v3.activity.button.watchall=Merkitse kaikki katsotuiksi
 sidebar.sash.tooltip=F7: Sivupalkin n\u00e4ytt\u00f6/sulkeminen
 sidebar.expand.tooltip=N\u00e4yt\u00e4 sivupalkki
 sidebar.dropdown.tooltip=N\u00e4yt\u00e4 sivupalkki valikkona
@@ -2547,19 +2560,24 @@ ConfigTransferAutoSpeed.auto.speed.neural=Auto-Speed (Neural,Gudy Alpha)
 ConfigView.label.autoopen.downloadbars=... torrentin seurantapalkki, kun
 ConfigView.label.autoopen=Avaa automaattisesti
 ConfigView.label.autoopen.detailstab=... torrentin yksityiskohdat-sivu, kun
+ConfigView.label.systray=Ilmoitusalue (System Tray)
 ConfigView.section.interface.legacy=Perinteiset optiot
 v3.MainWindow.menu.contentnetworks.manage=HD Networks -asetukset
+v3.dialog.cnclose.title=%1 suljettu
+v3.dialog.cnclose.subtitle=Tiedoksi
+v3.dialog.cnclose.info1=Olet sulkenut er\u00e4\u00e4n HD Networkin
+v3.dialog.cnclose.info2=Jos haluat avata t\u00e4m\u00e4n HD Networkin uudelleen, voit tehd\u00e4 sen "HD Networks"-valikosta ikkunan yl\u00e4osassa. 
+v3.dialog.cnclose.noshow=\u00c4l\u00e4 n\u00e4yt\u00e4 uudelleen
+v3.dialog.cnmanage.title=Hallitse HD Network -asetuksia
+v3.dialog.cnmanage.intro=Voit valita allaolevasta listasta, mitk\u00e4 sis\u00e4lt\u00f6verkot haluat n\u00e4hd\u00e4 "HD Networks"-valikossa
 TableColumn.header.#.info=Latausj\u00e4rjestyksen numero
 TableColumn.header.category.info=Luokka, johon torrent-tiedosto on asetettu.
 TableColumn.header.DateCompleted.info=Torrentin latauksen valmistumisp\u00e4iv\u00e4
 TableColumn.header.AzProduct.info=Torrentin l\u00e4hdeverkko
 TableColumn.header.health.info=Yhteyden ja siirron tila (katso lis\u00e4tietoja Ohje-valikosta).
-TableColumn.header.Info.info=Vuze-sis\u00e4ll\u00f6n detaljitietojen avaamispainike
 TableColumn.header.maxuploads.info=Hy\u00f6dynnett\u00e4vien l\u00e4hetyspaikkojen enimm\u00e4ism\u00e4\u00e4r\u00e4.
 TableColumn.header.name.info=Torrent-tiedoston kohteen nimi.
 TableColumn.header.unopened.info=Tieto siit\u00e4, onko torrent jo avattu
-TableColumn.header.Quality.info=Vize-sis\u00e4ll\u00f6n laatutaso, esim. HD, SD 
-TableColumn.header.RateIt.info=Vuze-sis\u00e4ll\u00f6n arvostelumahdollisuus
 TableColumn.header.savepath.info=Kohde, johon tietoja tallennetaan.
 TableColumn.header.SeedingRank.info=Mit\u00e4 korkeampi luku, sit\u00e4 t\u00e4rke\u00e4mp\u00e4\u00e4 on saada l\u00e4hetetty\u00e4.
 TableColumn.header.shareRatio.info=Torrent-tiedoston oma l\u00e4hetysm\u00e4\u00e4r\u00e4 suhteessa omaan latausm\u00e4\u00e4r\u00e4\u00e4n.
@@ -2568,7 +2586,6 @@ TableColumn.header.upspeed.info=Torrent-tiedoston l\u00e4hetysnopeus.
 TableColumn.header.downspeed.info=Torrent-tiedoston latausnopeus.
 TableColumn.header.up.info=Kohteen l\u00e4hetysm\u00e4\u00e4r\u00e4.
 TableColumn.header.down.info=Ladattu m\u00e4\u00e4r\u00e4.
-TableColumn.header.videoLength.info=Videon toistoaika
 TableColumn.header.ProgressETA.info=Yhdist\u00e4 Tila, Valmistuminen, ETA ja nopeus yhteen moniriviseen sarakkeeseen.
 TableColumn.header.eta.info=Arvioitu aika, jonka kuluttua lataus on valmistunut.
 Pieces.column.#.info=Osan numero
@@ -2624,7 +2641,10 @@ ConfigView.option.dm.dblclick.details=Avaa torrentin yksityiskohdat
 ConfigView.option.dm.dblclick.show=N\u00e4yt\u00e4 tiedosto
 ConfigView.option.dm.dblclick.show._mac=N\u00e4yt\u00e4 tiedosto(t) Finderissa
 ConfigView.option.dm.dblclick.show._windows=N\u00e4yt\u00e4 tiedosto(t) Windows Explorerissa
+Button.reload=Lataa uudelleen
 general.enter.cookies=Ev\u00e4steet (cookies)
+MyTorrentsView.menu.clear_alloc_data=Resetoi tiedostojen allokointitieto
+DiskManager.error.nospace=Ei riitt\u00e4v\u00e4sti levytilaa
 DiskManager.error.nospace_fat32={DiskManager.error.nospace} - tarkista {wiki.fat32}
 ConfigView.section.file.rename.incomplete=Lis\u00e4\u00e4 p\u00e4\u00e4te keskener\u00e4isiin tiedostoihin
 dlg.corewait.title=Vuzea k\u00e4ynnistet\u00e4\u00e4n
@@ -2633,4 +2653,38 @@ library.core.wait=Odota hetki...\nVuze on k\u00e4ynnistym\u00e4ss\u00e4
 ConfigView.label.StartUIBeforeCore=K\u00e4ynnist\u00e4 k\u00e4ytt\u00f6liittym\u00e4 ennen Vuzen ydint\u00e4 
 general.add.friends=Lis\u00e4\u00e4 yst\u00e4vi\u00e4!
 general.all.friends=Kaikki yst\u00e4v\u00e4t
-ConfigView.label.alwaysShowLibraryHeader=N\u00e4yt\u00e4 otsikkorivi aina (Siirrot-ikkuna)
+TableColumn.header.class=Luokka
+rcm.rc_tracker.tt=Valitse selataksesi seurantapalvelinta
+rcm.rc_hash.tt=Valitse ladataksesi t\u00e4m\u00e4 sis\u00e4lt\u00f6
+rcm.rc_title.tt=Valitse etsi\u00e4ksesi t\u00e4t\u00e4 sis\u00e4lt\u00f6\u00e4
+TableColumn.menu.maxuploads=# Max l\u00e4hetyspaikkoja
+ConfigView.label.alwaysShowLibraryHeader=N\u00e4yt\u00e4 otsikko/suodatinrivi aina (Siirrot-ikkuna)
+ConfigView.section.style.forceSIValues=N\u00e4yt\u00e4 arvot IEC-arvoina riippumatta esitysyksik\u00f6st\u00e4 yhteensopivuussyist\u00e4 (esim. 1MB = 1MiB = 1048576B)
+ConfigView.label.enableSystrayToolTip=N\u00e4yt\u00e4 nopeustiedot hiiren ollessa kohdalla
+button.nothanks=Ei kiitos
+webui.pairingenable=Mahdollista paritus
+webui.group.access=P\u00e4\u00e4syoikeudet
+ConfigView.section.Pairing=Paritus
+pairing.accesscode=Tunnistuskoodi
+pairing.ac.getnew=Aseta uusi tunnistuskoodi
+pairing.ac.getnew.create=Luo
+pairing.ipv4=IPv4-osoite
+pairing.ipv6=IPv6-osoite
+pairing.host=Koneen osoite (DNS-nimi)
+pairing.group.explicit=Erityiset asetukset
+pairing.explicit.enable=K\u00e4yt\u00e4 erityisasetuksia
+pairing.explicit.info=Normaalisti IP-erityisasetuksia ei tarvita, koska ne m\u00e4\u00e4rittyv\u00e4t automaattisesti.\n'Koneen osoite' -m\u00e4\u00e4rityst\u00e4 voidaan k\u00e4ytt\u00e4\u00e4 esim. jos sinulla on DynDNS-tili ja soveltuva ohjelmisto dynaamisen IP-osoitteen hallintaan.
+pairing.op.fail=Paritus ep\u00e4onnistui
+pairing.alloc.fail=Uuden tunnistuskoodin asetus ep\u00e4onnistui\n%1
+pairing.enable=Mahdollista Vuzen ja et\u00e4sovellusten/liittymien paritus
+pairing.status.info=Tila
+pairing.status.registered=P\u00e4ivitys onnistui (%1)
+pairing.status.pending=P\u00e4ivitys suoritetaan %1
+pairing.status.initialising=Alustetaan
+pairing.status.disabled=Pois p\u00e4\u00e4lt\u00e4
+pairing.view.registered=Valitse n\u00e4hd\u00e4ksesi rekister\u00f6intitiedot
+webui.pairing.info.n=Paritus on pois p\u00e4\u00e4lt\u00e4. Katso lis\u00e4tietoja Yhteys->Paritus-asetuksista
+webui.pairing.info.y=Paritus on mahdollista. Katso lis\u00e4tietoja Yhteys->Paritus-asetuksista.
+webui.enable=Toiminto k\u00e4yt\u00f6ss\u00e4 (*)
+ConfigView.section.rss=Paikallinen RSS jne.
+Button.removeAll=Poista kaikki
diff --git a/org/gudy/azureus2/internat/MessagesBundle_hu_HU.properties b/org/gudy/azureus2/internat/MessagesBundle_hu_HU.properties
index dedae0c..5497f08 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_hu_HU.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_hu_HU.properties
@@ -152,7 +152,7 @@ ConfigView.label.autoupdate=Friss\u00edt\u00e9s p\u00e1rbesz\u00e9dablak megnyit
 ConfigView.label.openconsole=Konzol megnyit\u00e1sa ind\u00edt\u00e1skor
 ConfigView.label.openconfig=Be\u00e1ll\u00edt\u00e1sok megnyit\u00e1sa ind\u00edt\u00e1skor
 ConfigView.label.startminimized=Kis m\u00e9retben indul
-ConfigView.label.ircwiki=Tov\u00e1bbi inform\u00e1ci\u00f3k: http://azureus.aelitis.com/wiki/index.php/Rules_for_IRC
+ConfigView.label.ircwiki=Tov\u00e1bbi inform\u00e1ci\u00f3k: http://wiki.vuze.com/index.php/Rules_for_IRC
 ConfigView.label.ircserver=Szerver
 ConfigView.label.ircchannel=Csatorna
 ConfigView.label.irclogin=Becen\u00e9v
@@ -1906,7 +1906,7 @@ UIDebugGenerator.complete.title=Hibakeres\u00e9s Gener\u00e1l\u00e1sa Befejezve
 UIDebugGenerator.complete.text=K\u00fcld el a '%1' f\u00e1jlt a az-bugreports at azureus-inc.com c\u00edmre\n\n Az OK gombbal a f\u00e1jlhoz ugrassz.
 ConfigView.section.style.showProgramIcon=Program ikonj\u00e1nak mutat\u00e1sa a n\u00e9v oszlopban
 ConfigView.section.style.showProgramIcon.tooltip=\u00dajranyit\u00e1s sz\u00fcks\u00e9ges a be\u00e1ll\u00edt\u00e1sok \u00e9rv\u00e9nyes\u00edt\u00e9s\u00e9hez
-swt.alert.cant.update="%3" helyr\u0151l bet\u00f6lt\u00f6tt SWT k\u00f6nyvt\u00e1rat nem lehet automatikusan friss\u00edteni a %1 verzi\u00f3r\u00f3l a %2 verzi\u00f3ra (innen kell let\u00f6lteni: "%4"). N\u00e9zd meg a<A HREF="http://azureus.aelitis.com/wiki/index.php/SWT_Cant_Auto_Update"> wiki-t</A> a r\u00e9szletek\u00e9rt.
+swt.alert.cant.update="%3" helyr\u0151l bet\u00f6lt\u00f6tt SWT k\u00f6nyvt\u00e1rat nem lehet automatikusan friss\u00edteni a %1 verzi\u00f3r\u00f3l a %2 verzi\u00f3ra (innen kell let\u00f6lteni: "%4"). N\u00e9zd meg a<A HREF="http://wiki.vuze.com/index.php/SWT_Cant_Auto_Update"> wiki-t</A> a r\u00e9szletek\u00e9rt.
 authenticator.savepassword=Jelsz\u00f3 megjegyz\u00e9se
 ConfigView.section.security.clearpasswords=T\u00e1rolt jelszavak t\u00f6rl\u00e9se
 ConfigView.section.security.clearpasswords.button=T\u00f6r\u00f6l
diff --git a/org/gudy/azureus2/internat/MessagesBundle_it_IT.properties b/org/gudy/azureus2/internat/MessagesBundle_it_IT.properties
index 35584be..55bb969 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_it_IT.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_it_IT.properties
@@ -26,7 +26,7 @@ MainWindow.menu.closealldetails=Chiudi &tutti i dettagli
 MainWindow.menu.closealldownloadbars=Chiudi tutte le &barre di download
 MainWindow.menu.language=&Lingua
 ConfigView.section.language=Lingua
-MainWindow.menu.window=&Finestra
+MainWindow.menu.window=Fi&nestra
 MainWindow.menu.window.minimize=&Minimizza
 MainWindow.menu.window.alltofront=Porta tutto in primo &piano
 MainWindow.menu.help=&Aiuto
@@ -130,7 +130,7 @@ ConfigView.label.disconnetseed=Disconnetti i seed quando si \u00e8 in seed
 ConfigView.label.switchpriority=Imposta automaticamente a bassa priorit\u00e0 quando in seed
 ConfigView.label.maxdownloads=Numero massimo di download simultanei [0: illimitato]\n - Non pu\u00f2 essere maggiore del numero massimo di torrent attivi
 ConfigView.label.maxdownloads.tooltip=Si potr\u00e0 sempre attivare un numero di download pari a quello impostato, con una sola eccezione.\nUn torrent che ha la Prima priorit\u00e0 potrebbe ricevere un ulteriore slot di download se assolutamente necessario.
-ConfigView.label.maxactivetorrents=Numero massimo di torrent attivi [0 : illimitato]\n - I torrent nuovi non possono partire se stai scaricando/inviando un numero di torrent pari a
+ConfigView.label.maxactivetorrents=Numero massimo di torrent attivi [0: illimitato]\n - I torrent nuovi non possono partire se stai scaricando/inviando un numero di torrent pari a
 ConfigView.label.priorityExtensions=Dai automaticamente priorit\u00e0 ai file con estensione \n (es: .txt;.nfo;.jpg)
 ConfigView.section.transfer=Trasferimento
 ConfigView.label.maxuploads=Numero massimo di invii per torrent
@@ -138,8 +138,8 @@ ConfigView.label.maxuploadspeed=Velocit\u00e0 massima di upload (globale) (KB/s)
 ConfigView.label.saveresumeinterval=Salva i dati del \u00abripristino veloce\u00bb ogni
 ConfigView.unlimited=Illimitato
 ConfigView.section.display=Visualizza
-ConfigView.label.opendetails=Apri automaticamente la scheda Dettagli
-ConfigView.label.openbar=Apri automaticamente la barra di download
+ConfigView.label.opendetails=Apri automaticamente la scheda Dettagli per
+ConfigView.label.openbar=Apri automaticamente la barra di download per
 ConfigView.label.use_old_speed_menus=Usa menu vecchio stile [richiede riavvio]
 ConfigView.label.closetotray=Il pulsante \u00abChiudi\u00bb minimizza nel vassoio di sistema
 ConfigView.label.minimizetotray=Il pulsante \u00abRiduci a icona\u00bb minimizza nel vassoio di sistema
@@ -154,7 +154,7 @@ ConfigView.label.ircwiki=Vedere http://www.azureuswiki.com/index.php/Rules_for_I
 ConfigView.label.ircchannel=Canale
 ConfigView.label.irclogin=Nome utente
 ConfigView.group.irctitle=Impostazioni IRC
-ConfigView.boolean.ircsendinfo=Autorizza l'invio delle tue impostazioni (anonimamente)\n agli operatori del canale, per meglio aiutarti
+ConfigView.boolean.ircsendinfo=Autorizza l'invio (anonimo) delle tue impostazioni\n agli operatori del canale, per aiutarti meglio
 ConfigView.boolean.irclog=Abilita la registrazione dell'attivit\u00e0 del canale (in IRC_log.htm)
 ConfigView.section.security=Sicurezza
 ConfigView.label.password=Proteggi Vuze usando una password\nVerr\u00e0 chiesta per ripristinarlo (dopo che \u00e8 stato ridotto ad icona) e quando viene avviato.
@@ -366,7 +366,7 @@ ConfigView.section.ipfilter.editFilter=Modifica filtro
 ConfigView.section.ipfilter.enable=Abilita
 PeersView.menu.close=&Chiudi
 seedmore.title=Il torrent non \u00e8 stato inviato abbastanza
-seedmore.shareratio=Il tuo rapporto di condivisione su questo torrent \u00e8
+seedmore.shareratio=Il tuo rapporto di condivisione per questo torrent \u00e8
 seedmore.uploadmore=Avere un rapporto di condivisione sotto il 100% non \u00e8 una buona cosa per la rete di BitTorrent.\nSi dovrebbe rimanere in seed ancora per un po'.\n\nSi \u00e8 sicuri di procedere?
 ConfigView.label.showpopuponclose=Mostra un popup di conferma quando interrompi l'invio di un file con rapporto di condivisione inferiore ad 1
 ConfigView.label.startNumSeeds=\nAvvia il seed se c'\u00e8 meno di\n - Ha la precedenza sulle altre regole
@@ -376,7 +376,7 @@ MyTorrentsView.menu.removeand=Rimuo&vi e
 MyTorrentsView.menu.removeand.deletetorrent=Elimina file &torrent
 MyTorrentsView.menu.removeand.deletedata=Elimina file par&ziale
 MyTorrentsView.menu.removeand.deleteboth=Elimina entram&bi
-deletedata.title=Eliminazione di contenuti
+deletedata.title=Eliminazione di contenuti multimediali
 deletedata.message1=Si vuole eliminare definitivamente \u00ab%1\u00bb?
 deletedata.noprompt=Non chiedere ancora
 MainWindow.menu.file.configure=Assistente di configura&zione...
@@ -399,8 +399,8 @@ configureWizard.transfer.maxActiveTorrents=Numero massimo di torrent attivi
 configureWizard.transfer.maxDownloads=Numero massimo di download simultanei
 configureWizard.transfer.maxUploadsPerTorrent=Numero massimo di upload per torrent
 configureWizard.nat.title=NAT / Porte del server
-configureWizard.nat.message=Per avere le migliori prestazioni, \u00e8 vivamente consigliato di essere completamente accessibili da Internet. Questo strumento permette di testare e/o cambiare le porte usate per le connessioni in entrata.\n\nNOTA: Vengono testate solo le connessioni TCP. Il database distribuito ha bisogno anche di connessioni UDP in entrata, ma visualizzer\u00e0 una notifica se scopre di essere bloccato da un firewall.\n\nNOTA: La porta TCP 6880 \u00e8 riservata internamente, quindi non pu\u00f2 essere usata.
-configureWizard.nat.test=Testa
+configureWizard.nat.message=Per avere le migliori prestazioni, \u00e8 vivamente consigliato di essere completamente accessibili da Internet. Questo strumento permette di testare e/o cambiare le porte usate per le connessioni in entrata.\n\nNOTA: Vengono testate solo le connessioni TCP. Il database distribuito ha bisogno anche di connessioni UDP in entrata, ma visualizzer\u00e0 una notifica se scopre di essere bloccato da un firewall.\n\nNOTA: La porta TCP 6880 \u00e8 riservata all'uso interno, quindi non pu\u00f2 essere usata.
+configureWizard.nat.test=Prova
 configureWizard.nat.testing=Test delle porte
 configureWizard.nat.ok=Ok
 configureWizard.nat.ko=Errore NAT
@@ -491,10 +491,10 @@ MyTrackerView.uploaded=Inviati
 MyTrackerView.downloaded=Scaricato
 MyTrackerView.left=Rimanenti
 ConfigView.section.style=Interfaccia
-ConfigView.label.set_ui_transfer_speeds=Ignora le velocit\u00e0 di trasferimento selezionabili
+ConfigView.label.set_ui_transfer_speeds=Modifica le velocit\u00e0 di trasferimento selezionabili
 ConfigView.label.set_ui_transfer_speeds.description=Si pu\u00f2 scegliere di definire manualmente le velocit\u00e0 predefinite di download e upload disponibili nella barra di stato del vassoio di sistema.\nI valori devono essere separati da virgole.
-ConfigView.label.set_ui_transfer_speeds.description.download=Imposta la velocit\u00e0 di download (KB/s)
-ConfigView.label.set_ui_transfer_speeds.description.upload=Imposta la velocit\u00e0 di upload (KB/s)
+ConfigView.label.set_ui_transfer_speeds.description.download=Velocit\u00e0 di download disponibili (KB/s)
+ConfigView.label.set_ui_transfer_speeds.description.upload=Velocit\u00e0 di upload disponibili (KB/s)
 ConfigView.section.style.useCustomTabs=Usa schede chiudibili (necessario riavvio)
 MainWindow.menu.view.plugins=&Plugin
 fileDownloadWindow.saveTorrentIn=Salva il file torrent in
@@ -510,7 +510,7 @@ openUrl.title=Apri URL
 MyTorrentsView.menu.host.error.title=Impossibile ospitare il torrent
 MyTorrentsView.menu.host.error.message=Si \u00e8 verificato il seguente errore nel tentativo di ospitare il torrent:
 ConfigView.section.tracker.pollinterval=Intervallo di poll client tracker (sec)
-ConfigView.section.tracker.publishenable=Pubblica i dettagli del torrent in \u00ab<tracker_url>\u00bb
+ConfigView.section.tracker.publishenable=Pubblica i dettagli del torrent in \u00ab<url_del_tracker>\u00bb
 ConfigView.section.tracker.ip=Indirizzo IP esterno del tracker
 ConfigView.section.style.enableXPStyle=Abilita lo stile XP (riavvio necessario)
 IPChecker.external.service.dyndns.description=Servizi di rete di DNS dinamico, LLC
@@ -575,12 +575,12 @@ ConfigView.section.style.graphicsUpdate=Aggiorna barre grafiche ogni N aggiornam
 ConfigView.section.style.reOrderDelay=Riordina le tabelle ogni N aggiornamenti della GUI [0: mai]
 ConfigView.section.style.reOrderDelay.never=Mai
 ConfigView.section.logging=Log
-ConfigView.section.logging.enable=Abilita il file di log
-ConfigView.section.logging.logdir=Cartella del file di log
+ConfigView.section.logging.enable=Abilita il file di registro
+ConfigView.section.logging.logdir=Cartella del file di registro
 ConfigView.section.logging.choosedefaultsavepath=Selezionare la cartella per il salvataggio
 GeneralView.label.updatein.querying=Interrogazione...
 configureWizard.nat.sharePort=Usa una singola porta di ascolto per tutti i torrent
-ConfigView.section.logging.maxsize=Dimensione massima del file di log
+ConfigView.section.logging.maxsize=Dimensione massima del file di registro
 ConfigView.section.tracker.passwordenableweb=Abilita password sui tracker web
 ConfigView.section.tracker.passwordenabletorrent=Abilita password per i torrent
 ConfigView.section.tracker.username=Nome utente
@@ -593,7 +593,6 @@ TableColumn.header.shareRatio=Rapporto condiv.
 MyTorrentsView.menu.editTableColumns=Impostazioni &colonna
 wizard.operationfailed=Operazione non riuscita
 authenticator.title=Autenticazione richiesta
-authenticator.realm=Reame
 authenticator.user=Nome utente
 ConfigView.label.allowSendVersion=Consenti a Vuze di inviare, in modo anonimo, il numero di versione e un identificativo casuale quando controlla se \u00e8 disponibile una nuova versione.
 ConfigView.label.version.info.link=Fare clic qui per maggiori dettagli sulle informazioni inviate al server di aggiornamento
@@ -612,13 +611,13 @@ TrayWindow.menu.stopalldownloads=&Ferma tutti i download
 ConfigView.section.tracker.sslport.info=Guarda le FAQ per maggiori informazioni.
 wizard.tracker.ssl=Usa SSL
 ConfigView.label.playdownloadfinished=Riproduci un suono al completamento del download
-ConfigView.label.popupdownloadfinished=Mostra un avviso quando un download \u00e8 completato
-ConfigView.label.popupfilefinished=Mostra un avviso quando un file \u00e8 completato
+ConfigView.label.popupdownloadfinished=Mostra un avviso quando viene completato un download
+ConfigView.label.popupfilefinished=Mostra un avviso quando viene completato un file
 TableColumn.header.pieces=Parti
 TableColumn.header.pieces.info=Barra che rappresenta le parti scaricate
 TableColumn.header.completion=Completamento
 TableColumn.header.completion.info=Rappresentazione grafica della percentuale scaricata
-ConfigView.section.style.showdownloadbasket=Mostra Cestino dei Download (per scaricare un file .torrent, trascinarlo e rilasciarlo sull'icona)
+ConfigView.section.style.showdownloadbasket=Mostra il Cesto dei Download (per scaricare un file .torrent, trascinarlo e rilasciarlo sull'icona)
 ConfigView.section.style.alwaysShowTorrentFiles=Mostra sempre i file torrent in Dettagli/File
 wizard.multitracker=Aggiungi informazioni multi-tracker nel torrent
 wizard.multitracker.title=Multi-tracker
@@ -657,7 +656,7 @@ GeneralView.menu.selectTracker=Seleziona
 ConfigView.section.stats.xslfile=Nome del file XSL
 ConfigView.section.stats.xslfiledetails=Sar\u00e0 incluso nell'intestazione del file delle statistiche tramite il tag <?xml-stylesheet>
 ConfigView.label.savetorrentbackup=Salva backup
-ConfigView.section.tracker.forceport=Forza i torrent esterni ospitati alla porta di default
+ConfigView.section.tracker.forceport=Forza la porta predefinita per i torrent esterni ospitati
 ConfigView.section.ipfilter.allow=Autorizza questi intervalli (di default li blocca)
 ConfigView.section.ipfilter.list.inrange=era nel range
 ConfigView.section.ipfilter.list.notinrange=non era in nessun range
@@ -693,7 +692,7 @@ MainWindow.menu.view.stats=&Statistiche
 SpeedView.title.full=Statistiche
 SpeedView.downloadSpeed.title=Velocit\u00e0 di download
 SpeedView.uploadSpeed.title=Velocit\u00e0 di upload
-ConfigView.section.style.useSIUnits=Usa le unit\u00e0 di misura SI (KB -> KiB etc.)
+ConfigView.section.style.useSIUnits=Usa le unit\u00e0 di misura del SI (KB -> KiB, ecc.)
 iconBar.top.tooltip=Sposta in alto
 iconBar.bottom.tooltip=Sposta in basso
 TableColumn.header.health=Salute
@@ -708,7 +707,6 @@ ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Questa opzione aggiorna
 #
 #2.0.7.0
 #
-ConfigView.section.style.verticaloffset=Offset grafico verticale (correzione per GTK)
 security.certtruster.title=Avviso di certificato di sicurezza
 security.certtruster.intro=Il certificato di sicurezza proviene da una compagnia non ancora autorizzata
 security.certtruster.resource=Risorsa:
@@ -761,7 +759,7 @@ ConfigView.section.sharing.usessl=Usa SSL per le risorse condivise (richiede la
 ConfigView.section.style.dropdiraction=Azione connessa al trascinamento e rilascio delle cartelle
 ConfigView.section.style.dropdiraction.opentorrents=Apri torrent
 ConfigView.section.style.dropdiraction.sharefolder=Condividi cartella
-ConfigView.section.style.dropdiraction.sharefoldercontents=Condividi contenuti
+ConfigView.section.style.dropdiraction.sharefoldercontents=Condividi contenuti multimediali
 #
 # 2.0.7.x
 #
@@ -776,7 +774,7 @@ ConfigView.label.ignoreCase=Ignora Maiuscolo/Minuscolo
 ConfigView.label.ignoreSeeds=Ignora i torrent con almeno
 ConfigView.label.importdirectory=Importa cartella
 ConfigView.label.minPeersToBoostNoSeeds.tooltip=I torrent con nessun seed e meno peer di quanto specificato\nsaranno spostati pi\u00f9 in basso nella coda.
-ConfigView.label.minPeersToBoostNoSeeds=Diminuisci il punteggio di seed ai torrent con nessun seed e meno di
+ConfigView.label.minPeersToBoostNoSeeds=Diminuisci il punteggio di seed ai torrent senza seed e con meno di
 ConfigView.label.minSeedingTime.tooltip=Il punteggio di seed pu\u00f2 variare spesso e in breve tempo, a volte causando l'avvio automatico di alcuni torrent, che immediatamente dopo vengono fermati e messi in coda.\nQuesto allevia il problema forzando il torrent a stare in seed per un certo periodo. Lo si pu\u00f2 comunque fermare manualmente se si vuole.
 ConfigView.label.minSeedingTime=Numero minimo di secondi di seed
 ConfigView.label.minSpeedForActiveDL.tooltip=Uno slot di download viene sempre usato per i primi 30 secondi\ndopo che il torrent incompleto \u00e8 stato avviato.
@@ -803,13 +801,13 @@ ConfigView.label.seeding.firstPriority.info=I torrent con \u00abPrima priorit\u0
 ConfigView.label.seeding.firstPriority.FP=Prima priorit\u00e0
 ConfigView.label.seeding.firstPriority=La \u00abPrima priorit\u00e0\u00bb sar\u00e0 data ai torrent con
 ConfigView.label.seeding.firstPriority.following=dei seguenti requisiti:
-ConfigView.label.seeding.firstPriority.shareRatio=Un rapporto di condivisione al disotto del
+ConfigView.label.seeding.firstPriority.shareRatio=Un rapporto di condivisione al di sotto del
 ConfigView.label.seeding.firstPriority.seedingMinutes=Un tempo trascorso, dal cambio da download in seed,
 ConfigView.label.seeding.firstPriority.DLMinutes=Un tempo trascorso dall'inizio del download
 ConfigView.label.seeding.numPeersAsFullCopy.tooltip=Assumendo che ci sia 1 copia completa ogni N peer, si riduce il punteggio dei torrent con un gran numero di peer.\nProbabilmente, i torrent con un gran numero di peer hanno anche un alto traffico.\nQuesta opzione non cambia il numero di seed mostrati.
-ConfigView.label.seeding.numPeersAsFullCopy=Assumi che ci sia 1 copia completa del torrent ogni\n[0 : disabilitato]
+ConfigView.label.seeding.numPeersAsFullCopy=Assumi che ci sia 1 copia completa del torrent ogni\n[0: disabilitato]
 ConfigView.label.seeding.preferLargerSwarms.tooltip=Se si effettua principalmente il seed di torrent con peer che sono \u00abbloccati\u00bb, ha senso preferire i file con pi\u00f9 swarm\nQuando si effettua principalmente il seed di torrent con alta disponibilit\u00e0, ha senso preferire i file con meno swarm.
-ConfigView.label.seeding.preferLargerSwarms=Quando pi\u00f9 torrent hanno lo stesso punteggio, preferisci quelli gli swarm pi\u00f9 grandi
+ConfigView.label.seeding.preferLargerSwarms=Quando pi\u00f9 torrent hanno lo stesso punteggio, preferisci quelli con pi\u00f9 utenti
 ConfigView.label.seeding.rankType.none.tooltip=Ordine basato sulla colonna \u00abn\u00b0\u00bb
 ConfigView.label.seeding.rankType.none=Nessuno
 ConfigView.label.seeding.rankType.peer.tooltip=pi\u00f9 peer e meno seed => punteggio maggiore\nQuesto metodo rende minimo il numero di torrent da mantenere attivi per raggiungere il limite di upload.
@@ -817,7 +815,7 @@ ConfigView.label.seeding.rankType.peer=Conteggio dei peer pesato
 ConfigView.label.seeding.rankType.peerSeed.options=Opzioni rapporto peer/seed
 ConfigView.label.seeding.rankType.peerSeed.tooltip=Pi\u00f9 alto il rapporto => Pi\u00f9 alto il punteggio
 ConfigView.label.seeding.rankType.peerSeed=Rapporto peer/seed
-ConfigView.label.seeding.rankType.seed.fallback=Usa il rapporto peer/seed se ci sono pi\u00f9 di\n[0 : mai]
+ConfigView.label.seeding.rankType.seed.fallback=Usa il rapporto peer/seed se ci sono pi\u00f9 di\n[0: mai]
 ConfigView.label.seeding.rankType.seed.options=Opzioni di Conto dei soli seed
 ConfigView.label.seeding.rankType.seed.tooltip=Pi\u00f9 basso il numero di seed => Pi\u00f9 alto il punteggio
 ConfigView.label.seeding.rankType.seed=Conto dei soli seed
@@ -853,7 +851,7 @@ MySeedersView.header=Torrent completati
 TableColumn.header.availability.info=N\u00b0 copie complete
 TableColumn.header.availability=Disponibilit\u00e0
 TableColumn.header.category=Categoria
-MyTorrentsView.header=Torrent incompleti
+MyTorrentsView.header=Torrent non completati
 TableColumn.header.maxuploads=N\u00b0 max di upload
 MyTorrentsView.menu.category.delete=&Elimina categoria
 MyTorrentsView.menu.forceStart=&Forza l'avvio
@@ -870,10 +868,10 @@ StartStopRules.FP0Peers=PP / 0 peer
 StartStopRules.0Peers=0 peer
 StartStopRules.numSeedsMet=N\u00b0 seed OK
 StartStopRules.ratioMet=Peer:Seed OK
-StartStopRules.shareRatioMet=Rapporto di condivisione Ok
+StartStopRules.shareRatioMet=Rapporto di condivisione OK
 StartStopRules.waiting=In attesa
 StartStopRules.firstPriority=Prima priorit\u00e0
-ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=Condividi contenuti (ricorsivo)
+ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=Condividi contenuti multimediali (ricorsivo)
 DownloadManager.error.unabletostartserver=Impossibile avviare il server - controllare la configurazione delle porte in ingresso e i permessi del firewall per le applicazioni che fanno da server.
 GeneralView.label.creationdate=Creato il :
 ConfigView.section.tracker.announcescrapepercentage=Intervallo di scrape corrispondente a una % dell'et\u00e0 dell'announce\nad esempio 200 = \u00ab2:1\u00bb. 0 = \u00ablascia decidere il peer\u00bb
@@ -894,7 +892,7 @@ ConfigView.section.proxy=Proxy
 ConfigView.section.proxy.enable_proxy=Abilita proxy
 ConfigView.section.proxy.port=Porta
 ConfigView.section.proxy.username=Nome utente
-ConfigView.section.proxy.enable_socks=Ho un SOCKS proxy
+ConfigView.section.proxy.enable_socks=Ho un proxy SOCKS
 wizard.createtorrent.extrahashes=Aggiungi gli hash per le altre reti (ad esempio Gnutella2, eDonkey2000)
 GeneralView.label.connected=connesso
 GeneralView.label.in_swarm=nello swarm
@@ -984,7 +982,7 @@ swt.updater.downloader.downloading=Sto scaricando SWT da
 swt.updater.urlsgetter.downloading=Ottengo una lista di mirror da
 swt.updater.urlsgetter.platform=SWT per la piattaforma :
 window.updateswt.ignore=Ignora
-ConfigView.section.style.useFancyTabs=Usa i Fancy tab
+ConfigView.section.style.useFancyTabs=Usa le linguette arrotondate
 splash.initializeGM=Inizializzazione del gestore torrent globale
 splash.loadingTorrents=Caricamento dei torrent
 MyTorrentsView.menu.thisColumn.sort=&Ordina
@@ -1003,7 +1001,7 @@ MainWindow.menu.view.irc.moved=Adesso Irc \u00e8 disponibile solo come plugin, v
 MyTrackerView.webui.contextmenu.copyurl=Copia l'URL del torrent negli appunti
 ConfigView.section.file.torrent.ignorefiles=File da ignorare quando si creano/eliminano torrent\n - per esempio \u00ab.DS_Store;Thumbs.db\u00bb
 Torrent.create.progress.ignoringfile=Sto ignorando il file
-ConfigView.section.style.useUnitsRateBits=Usa i bit invece dei byte per i valori basati sui byte (KiB/s->Kibit/s etc.)
+ConfigView.section.style.useUnitsRateBits=Usa i bit invece dei byte per i valori basati sui byte (KiB/s -> Kibit/s, ecc.)
 ConfigView.section.interface.resetassoc=Ripristina le associazioni dei file (.torrent)
 ConfigView.section.interface.resetassocbutton=Ripristina
 ConfigView.section.interface.checkassoc=Controlla l'associazione dei file all'avvio
@@ -1090,30 +1088,30 @@ webui.rootres=Risorsa principale (*)
 webui.mode=Modalit\u00e0 (*)
 webui.mode.info=La modalit\u00e0 puo essere\n\t\u00abfull\u00bb\t= tutte le operazioni disponibili (predefinito)\n\t\u00abview\u00bb\t= solo visione (ma pu\u00f2 modificare la frequenza di aggiornamento).
 webui.access=Accesso (*)
-webui.access.info=L'accesso puo essere \n\t\u00ablocale\u00bb\t= solo il computer locale pu\u00f2 connettersi\n\t\u00abtutti\u00bb\t= accesso senza limiti (default)\n\tIP\t= ad esempio 192.168.0.2\t\t\tsolamente un IP\n\tIP1-IP2\t= ad esempio 192.168.0.1-192.168.0.255\trange di IP
+webui.access.info=L'accesso puo essere \n\t\u00ablocal\u00bb\t= solo il computer locale pu\u00f2 connettersi\n\t\u00aball\u00bb\t= accesso senza limiti (default)\n\tIP\t\t= ad esempio 192.168.0.2\t\t\t\tsolo un IP\n\tIP1-IP2\t= ad esempio 192.168.0.1-192.168.0.255\trange di IP
 GeneralView.label.maxdownloadspeed=Limite down.
 Security.keystore.corrupt=Errore nel caricamento del keystore \u00ab%1\u00bb, cancellarlo e ricreare/reinportare i certificati.
 Security.keystore.empty=Il keystore \u00e8 vuoto. Creare un certificato autofirmato (vedere \u00abStrumenti -> Configurazione -> Sicurezza\u00bb) o importarne uno gi\u00e0 esistente in \u00ab%1\u00bb.
 webui.restart.info=Le modifiche ai parametri indicati con una (*) richiedono un riavvio per funzionare correttamente.
 GeneralView.label.maxdownloadspeed.tooltip=Velocit\u00e0 massima di download [0: illimitata]
 upnp.enable=Abilita UPnP
-upnp.info=Universal Plug and Play (UPnP) permette il mappaggio automatico delle porte sui router abilitati all'UPnP.
+upnp.info=Universal Plug and Play (UPnP) permette la mappatura automatica delle porte sui router abilitati all'UPnP.
 upnp.mapping.dataport=Porta di ascolto
 upnp.mapping.tcptrackerport=Porta TCP del tracker
 upnp.mapping.udptrackerport=Porta UDP del tracker
-upnp.alert.differenthost=UPnP: il mappaggio \u00ab%1\u00bb \u00e8 stato riservato da \u00ab%2\u00bb - selezionare una porta differente.
-upnp.alert.mappingok=UPnP: mappaggio \u00ab%1\u00bb stabilito.
-upnp.alert.mappingfailed=UPnP: mappaggio \u00ab%1\u00bb non riuscito.
-upnp.alertsuccess=Comunica il riuscito mappaggio
+upnp.alert.differenthost=UPnP: la mappatura \u00ab%1\u00bb \u00e8 stata riservata da \u00ab%2\u00bb - selezionare una porta differente.
+upnp.alert.mappingok=UPnP: mappatura \u00ab%1\u00bb stabilita.
+upnp.alert.mappingfailed=UPnP: mappatura \u00ab%1\u00bb non riuscita.
+upnp.alertsuccess=Comunica le mappature riuscite
 upnp.alert.lostdevice=UPnP: persa la connessione al servizio \u00ab%1\u00bb sulla periferica UPnP \u00ab%2\u00bb.
-upnp.grabports=Mappa le porte anche se sono possedute da un'altro computer
+upnp.grabports=Mappa le porte anche se sono utilizzate da un altro computer
 upnp.refresh.label=Aggiorna i mappaggi
 upnp.refresh.button=Aggiorna
-upnp.alert.mappinggrabbed=UPnP: mappaggio \u00ab%1\u00bb stabilito - acquisito da \u00ab%2\u00bb.
+upnp.alert.mappinggrabbed=UPnP: mappatura \u00ab%1\u00bb stabilita - acquisita da \u00ab%2\u00bb.
 upnp.mapping.tcpssltrackerport=Porta TCP con SSL del tracker
 upnp.alertothermappings=Segnala le porte utilizzate dagli altri computer
 upnp.alertdeviceproblems=Segnala problemi con la periferica UPnP
-upnp.trace_to_log=Scrivi informazioni di debug complete nel log
+upnp.trace_to_log=Scrivi informazioni di debug complete nel file registro
 upnp.wiki_link=Pagina della wiki di Vuze sull'UPnP
 upnp.refresh_mappings_on_bad_nat=Aggiorna automaticamente i mappaggi quando lo stato del NAT \u00e8 \u00abCon firewall\u00bb
 ConfigView.pluginlist.coreplugins=Sono stati caricati i seguenti plugin integrati:
@@ -1165,7 +1163,7 @@ ConfigView.section.file.perf.cache.size=Dimensione della cache (%1)
 MainWindow.menu.transfers=T&rasferimenti
 MainWindow.menu.transfers.startalltransfers=Av&via tutti
 MainWindow.menu.transfers.stopalltransfers=Fer&ma tutti
-MainWindow.menu.transfers.pausetransfers=&Pausa
+MainWindow.menu.transfers.pausetransfers=Metti in &pausa
 MainWindow.menu.transfers.resumetransfers=&Riprendi
 ConfigView.label.experimental.osx.kernel.panic.fix=Correzione sperimentale per problemi di kernel su sistemi OSX con doppia cpu [richiede riavvio]
 SystemTray.menu.pausetransfers=Metti in pausa i trasferimenti
@@ -1198,10 +1196,10 @@ CacheView.reads.avgsize=Dim. media
 openUrl.referrer=Pagina URL di riferimento :
 openUrl.referrer.info=Necessaria solamente per i siti internet che la richiedono
 ConfigView.label.maxuploadspeedseeding=Modifica la velocit\u00e0 quando si \u00e8 solo in seed a
-ConfigView.label.transfer.ignorepeerports=Ignora i peer con queste porte (separale con \u00ab;\u00bb, esempio \u00ab0;25\u00bb)
+ConfigView.label.transfer.ignorepeerports=Ignora i peer con queste porte (separale con \u00ab;\u00bb, per esempio \u00ab0;25\u00bb)
 ConfigView.section.proxy.enable_socks.peer=Abilita il passaggio su proxy delle comunicazioni con i peer (solo connessioni in uscita) [richiede riavvio]
 ConfigView.section.proxy.peer.informtracker=Informa il tracker delle limitazioni
-ConfigView.section.proxy.socks.version=Versione SOCKS
+ConfigView.section.proxy.socks.version=Versione di SOCKS
 PiecesView.legend.written=Scritto
 PiecesView.legend.requested=Richiesto
 PiecesView.legend.downloaded=Scaricato, in attesa di scrittura
@@ -1217,14 +1215,14 @@ ConfigView.section.security.choosetoolssavedir=Selezionare la cartella contenent
 ConfigView.section.proxy.peer.same=Usa le stesse impostazioni proxy per il tracker e i peer
 ConfigView.section.connection.network.max.simultaneous.connect.attempts=Massimo numero di tentativi di connessioni in uscita simultanei
 ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Numero massimo di nuovi tentativi di connessione in uscita che Vuze dovrebbe cercare di stabilire ogni volta.\nNOTA: Windows XP Service Pack 2 (SP2) impone un limite di 10 tentativi di connessione per tutto il sistema.\nIl valore predefinito \u00e8 8.
-ConfigView.section.file.perf.cache.size.explain=La cache \u00e8 usata per ridurre le letture/scritture sul disco. A meno che non si stia usando l'opzione java \u00ab-XX:MaxDirectMemorySize\u00bb per impostare esplicitamente la memoria disponibile per la cache e l'IO di rete, si dovrebbe tenere questo valore almeno %1 sotto la massima dimensione della memoria virtuale. L'attuale dimensione massima della memoria virtuale \u00e8 %2. Per informazioni su come cambiare questo valore, vedere il paragrafo MemoryUsage sul wiki (%3). Errori nell'uso di impostazioni delicate provocheranno problemi di \u00abMemoria esaurita\u00bb . Pi\u00f9 di 32MB di cache sono probabilmente eccessivi.
+ConfigView.section.file.perf.cache.size.explain=La cache \u00e8 usata per ridurre le letture/scritture sul disco. A meno che non si stia usando l'opzione java \u00ab-XX:MaxDirectMemorySize\u00bb per impostare esplicitamente la memoria disponibile per la cache e l'IO di rete, si dovrebbe tenere questo valore almeno %1 sotto la massima dimensione della memoria virtuale. L'attuale dimensione massima della memoria virtuale \u00e8 %2. Per informazioni su come cambiare questo valore, vedere il paragrafo MemoryUsage sul wiki (%3). Errori nell'uso di impostazioni delicate provocheranno problemi di \u00abMemoria esaurita\u00bb. Pi\u00f9 di 32MB di cache sono probabilmente eccessivi.
 MyTorrentsView.menu.setSpeed.unlimit=Nessun limite
 MyTorrentsView.menu.setSpeed.unlimited=Illimitato
 MyTorrentsView.menu.setSpeed.disable=Disabilita l'upload
 MyTorrentsView.menu.setSpeed.disabled=Disabilita
 MyTorrentsView.menu.setSpeed.slots=slot di
 GeneralView.label.maxuploadspeed=Limite di upload
-GeneralView.label.maxuploadspeed.tooltip=Velocit\u00e0 massima di upload [0 : illimitata]
+GeneralView.label.maxuploadspeed.tooltip=Velocit\u00e0 massima di upload [0: illimitata]
 MyTorrents.items.UpSpeedLimit.disabled=Nessun upload
 MyTorrents.items.UpSpeedLimit.unlimited=Illimitata
 TableColumn.header.maxupspeed=Max velocit\u00e0 di upload
@@ -1243,7 +1241,7 @@ FilesView.fullpath=Mostra il percorso completo
 FilesView.remaining=Parti restanti
 TableColumn.header.trackername=Nome del tracker
 TableColumn.header.trackername.info=Nome del tracker basato sull'URL dell'annuncio
-ConfigView.group.override=
+ConfigView.group.override=Opzioni per l'override
 ConfigView.section.file.perf.cache.notsmallerthan=Non mettere in cache file pi\u00f9 piccoli di (%1)
 PeersView.menu.blockupload=Blocca upload
 PeersView.menu.kickandban=Caccia e banna
@@ -1264,7 +1262,7 @@ DownloadManager.error.operationcancancelled=Operazione annullata
 Torrent.create.progress.cancelled=Operazione annullata
 sharing.progress.cancel=Annulla
 wizard.maketorrents.autoopen=Apri il torrent per il seed alla fine del processo
-ConfigView.section.sharing.rescanenable=Abilita periodici ricontrolli dello share per eventuali cambiamenti
+ConfigView.section.sharing.rescanenable=Controlla periodicamente lo share per eventuali cambiamenti
 ConfigView.section.sharing.rescanperiod=Intervallo di ricontrollo (sec)
 ConfigView.section.connection.advanced=Impostazioni di rete avanzate
 ConfigView.section.connection.advanced.mtu=Unit\u00e0 massima di trasmissione della linea (MTU)
@@ -1290,7 +1288,7 @@ ConfigView.section.tracker.passwordwebhttpsonly=Abilita accesso solo via HTTPS
 TableColumn.header.torrentpath=Posizione del torrent
 TableColumn.header.torrentpath.info=Posizione del torrent nel disco
 ConfigView.section.sharing.torrentcomment=Commenti per i torrent generati
-ConfigView.label.copyanddeleteratherthanmove=Copia e poi cancella i dati originali piuttosto che spostarli in una sola operazione - pu\u00f2 evitare perdite di dati su alcuni file system
+ConfigView.label.copyanddeleteratherthanmove=Copia e poi cancella i dati originali invece di spostarli in una sola operazione - pu\u00f2 evitare perdite di dati su alcuni file system
 ConfigView.label.openstatsonstart=Apri le Statistiche all'avvio
 swt.install.window.title=Installazione di plugin per Vuze
 swt.install.window.ok=Installa
@@ -1352,7 +1350,7 @@ ConfigView.section.tracker.tcpnonblocking=Usa l'I/O non bloccante per i processi
 ConfigView.section.tracker.nonblocking=Opzioni di non-bloccaggio
 ConfigView.section.tracker.nonblockingconcmax=Numero massimo di connessioni simultanee [0: illimitate]
 MyTorrentsView.menu.exportmenu=Esporta
-ConfigView.section.tracker.client.scrapeinfo=Disabilitare lo scrape impedir\u00e0 a molte delle regole di gestione della coda di funzionare poich\u00e9 dipendono dalle informazioni sullo swarm ricevute facendo lo scrape dei tracker.
+ConfigView.section.tracker.client.scrapeinfo=Disabilitare lo scrape impedir\u00e0 a molte delle regole di gestione della coda di funzionare perch\u00e9 dipendono dalle informazioni sullo swarm ricevute facendo lo scrape dei tracker.
 ConfigView.section.tracker.client.scrapeenable=Abilita lo scrape
 ConfigView.section.tracker.client.scrapestoppedenable=Fai lo scrape dei torrent che non sono attivi
 Scrape.status.disabled=Scrape disabilitato
@@ -1402,7 +1400,7 @@ ConfigView.label.seeding.firstPriority.ignore=Ignora le regole soprastanti della
 ConfigView.label.seeding.firstPriority.ignoreSPRatio=Torrent con un rapporto tra seed e peer superiore a
 ConfigView.label.seeding.firstPriority.ignore0Peer=Torrent con 0 peer
 ConfigView.section.tracker.sendjavaversionandos=Invia la versione di Java ed il nome del sistema operativo
-MagnetPlugin.contextmenu.exporturi=Copia il Magnet URI negli appunti
+MagnetPlugin.contextmenu.exporturi=Copia l'indirizzo Magnet negli appunti
 ConfigView.section.plugins.dht=DB distribuito
 dht.info=Questo plugin supporta il tracking decentralizzato, fra le altre cose, - disabilitarlo ridurr\u00e0 la possibilit\u00e0 di scaricare.
 dht.enabled=Abilita il database distribuito
@@ -1419,7 +1417,7 @@ ConfigView.section.file.nativedelete._windows=Sposta i file eliminati nel Cestin
 ConfigView.section.logging.generatediagnostics=Genera
 ConfigView.section.logging.netinfo=Genera informazioni sulla rete
 ConfigView.section.logging.statsinfo=Genera informazioni statistiche
-ConfigView.section.logging.generatediagnostics.info=Genera informazioni di diagnosi copiandole sulla clipboard e generando un file di log, se configurato.
+ConfigView.section.logging.generatediagnostics.info=Genera informazioni di diagnosi copiandole sulla clipboard e generando un file di registro, se configurato.
 ConfigView.section.sharing.privatetorrent=Torrent privato - accetta solamente i peer dal tracker
 MainWindow.menu.tools.nattest=Test &NAT / Firewall
 Button.apply=Applica
@@ -1482,7 +1480,7 @@ MainWindow.dht.status.failed=Errore del DHT
 MainWindow.dht.status.initializing=Inizializzazione del DHT in corso
 MainWindow.dht.status.users=%1 utenti
 MainWindow.dht.status.unreachable=DHT bloccato da firewall
-MainWindow.dht.status.unreachabletooltip=Sembra esserci un problema con il mappaggio della porta UDP del database distribuito (NAT/firewall)
+MainWindow.dht.status.unreachabletooltip=Sembra esserci un problema con la mappatura della porta UDP del database distribuito (NAT/firewall)
 MyTorrentsView.menu.setUpSpeed=Imposta la velocit\u00e0 di upload
 MyTorrentsView.menu.setDownSpeed=Imposta la velocit\u00e0 di download
 ConfigView.section.tracker.client.showwarnings=Mostra i messaggi di avviso restituiti dal tracker
@@ -1490,7 +1488,7 @@ dht.advanced=Abilita le impostazioni avanzate
 dht.advanced.group=Impostazioni avanzate
 dht.advanced.label=Modificare questi valori solo se si sa quello che si sta facendo
 dht.override.ip=Sovrascrivi indirizzo IP esterno
-ConfigView.section.logging.loggerenable=Abilita il log
+ConfigView.section.logging.loggerenable=Abilita la registrazione delle operazioni
 ConfigView.section.ipfilter.blockbanning=Banna un intero blocco di 256 indirizzi quando in quel blocco ne sono stati bannati almeno
 MyTrackerView.passive=Passivo
 TableColumn.header.swarm_average_speed=Velocit\u00e0 media dello swarm
@@ -1507,9 +1505,9 @@ ConfigView.label.playfilespeech=Parla quando un file \u00e8 stato scaricato
 ConfigView.label.playfilespeech.info=Il servizio di sintesi vocale funziona meglio con la lingua inglese.
 ConfigView.label.playfilefinished=Riproduci un suono quando un file \u00e8 stato scaricato
 ConfigView.label.backupconfigfiles=Fai copie di backup dei file di configurazione per permetterne il recupero
-ConfigView.section.tracker.client.scrapesingleonly=Disabilita l'aggregazione degli scrape per-tracker (pu\u00f2 aiutare con i tracker che riportano errori \u00abURL too long\u00bb (414))
-dht.ipfilter.log=Scrivi nel log le violazioni del filtro IP
-ConfigView.label.seeding.addForSeedingDLCopyCount=Considera \u00abaggiungi al seed\u00bb i download che hanno scaricato questo numero di copie
+ConfigView.section.tracker.client.scrapesingleonly=Disabilita l'aggregazione per tracker degli scrape (pu\u00f2 aiutare con i tracker che riportano errori \u00abURL too long\u00bb (414))
+dht.ipfilter.log=Registra le violazioni del filtro IP
+ConfigView.label.seeding.addForSeedingDLCopyCount=Considera l'aggiunta al seed dei download che hanno scaricato questo numero di copie
 ActivityView.legend.limit=Limite di velocit\u00e0
 ActivityView.legend.achieved=Velocit\u00e0 raggiunta
 ActivityView.legend.overhead=Traffico del protocollo
@@ -1541,15 +1539,15 @@ ConfigView.higher.mode.available=Nelle modalit\u00e0 utente pi\u00f9 avanzate so
 ConfigView.section.mode=Modalit\u00e0
 ConfigView.section.mode.title=Abilit\u00e0 dell'utente
 ConfigView.section.mode.beginner=Principiante
-ConfigView.section.mode.beginner.wiki.definitions=Vocabolario del BitTorrent
+ConfigView.section.mode.beginner.wiki.definitions=Glossario di BitTorrent (in inglese)
 ConfigView.section.mode.intermediate=Intermedio
-ConfigView.section.mode.intermediate.wiki.host=Ospitare file
-ConfigView.section.mode.intermediate.wiki.publish=Pubblicare file
+ConfigView.section.mode.intermediate.wiki.host=Ospitare file (in inglese)
+ConfigView.section.mode.intermediate.wiki.publish=Pubblicazione di file (in inglese)
 ConfigView.section.mode.advanced=Avanzata
-ConfigView.section.mode.advanced.wiki.main=Pagina iniziale del wiki
+ConfigView.section.mode.advanced.wiki.main=Pagina iniziale del wiki (in inglese)
 ConfigView.section.mode.beginner.text=Tutto quello di cui si ha bisogno per scaricare i torrent.\nUsare questa modalit\u00e0 se tutto quello che si vuole fare \u00e8 gestire i torrent.
-ConfigView.section.mode.intermediate.text=Accedi alle funzioni del tracker.\nUsare questa modalit\u00e0 per creare un tracker ed ospitare/pubblicare file.
-ConfigView.section.mode.advanced.text=Accesso alle impostazioni della rete.\nUsare questa modalit\u00e0 solo se si conosce cosa sono i MTU o i \u00abnon blocking I/O\u00bb...
+ConfigView.section.mode.intermediate.text=Possibilit\u00e0 di accedere alle funzioni del tracker.\nUsare questa modalit\u00e0 per creare un tracker ed ospitare/pubblicare file.
+ConfigView.section.mode.advanced.text=Accesso alle impostazioni della rete.\nUsare questa modalit\u00e0 solo se si conosce cosa sono gli MTU o i \u00abnon blocking I/O\u00bb...
 Files.column.storagetype=Tipo di archiviazione
 Files.column.fileext=Tipo
 FileItem.storage.linear=Lineare
@@ -1565,17 +1563,17 @@ configureWizard.welcome.usermodes=Queste impostazioni sull'abilit\u00e0 dell'ute
 FilesView.skip.confirm.delete.text=Troncare il file \u00ab%1\u00bb per risparmiare spazio?
 FilesView.rename.failed.title=Rinominazione/Reindirizzamento non riuscito
 FilesView.rename.failed.text=L'operazione non \u00e8 riuscita, probabilmente perch\u00e9 il percorso non \u00e8 valido.
-diagnostics.log_found=Vuze non si \u00e8 chiuso correttamente. Analizzare i <A HREF="%1">file di log diagnostici</A>. Vedere anche l'articolo <A HREF="http://www.azureuswiki.com/index.php/Vuze_disappears">Vuze Disappears</A> (in inglese) del wiki per maggiori informazioni.
+diagnostics.log_found=Vuze non si \u00e8 chiuso correttamente. Analizzare le <A HREF="%1">registrazioni diagnostiche</A>. Vedere anche l'articolo <A HREF="http://www.azureuswiki.com/index.php/Vuze_disappears">Vuze Disappears</A> (in inglese) del wiki per maggiori informazioni.
 ManagerItem.paused=In pausa
 Utils.link.visit=Visitare
-ConfigView.section.connection.serverport.wiki=Scelta di una buona porta
+ConfigView.section.connection.serverport.wiki=Scelta di una buona porta (in inglese)
 ConfigView.section.transfer.speeds.wiki=Impostazioni ottimali della velocit\u00e0
 installPluginsWizard.installMode.info.title=Informazioni
 installPluginsWizard.installMode.info.text=Vuze non ha bisogno di plugin per lavorare correttamente, apportano caratteristiche complementari per divertimento, automazione o controllo remoto.\nQuindi leggere attentamente la descrizione di ogni plugin prima di installarlo.\nLa maggior parte dei plugin sono sicuri da provare, comunque \u00e8 meglio non sovraccaricare la configurazione con plugin che non verranno usati.
 Views.plugins.Distributed.DB.title=DB distribuito
 Views.plugins.Distributed.Tracker.title=Tracker distribuito
 Views.plugins.Plugin.Update.title=Aggiornamento dei plugin
-openUrl.url.info=Supporta http, https, magnet e stringhe raw hex infohash
+openUrl.url.info=Supporta http, https, magnet e stringhe infohash grezze esadecimali
 TableColumn.header.swarm_average_completion=Media di completamento dei peer
 TableColumn.header.swarm_average_completion.info=La percentuale media di completamento dei peer nello swarm
 GeneralView.label.swarm_average_completion=Media di completamento:
@@ -1586,20 +1584,20 @@ MainWindow.nat.status.tooltip.probok=La raggiungibilt\u00e0 NAT era in OK, ma no
 MainWindow.nat.status.bad=Bloccato da firewall
 MainWindow.nat.status.tooltip.bad=Possibile problema di firewall o NAT (TCP), consultare il wiki se il problema persiste
 plugin.installer.recommended.plugin=Plugin raccomandato - considerarlo ed installarlo se richiesto
-LoggerView.pause=Pausa il log
+LoggerView.pause=Metti in pausa la registrazione delle operazioni
 LoggerView.clear=&Pulisci
 LoggerView.filter=Filtra
 LoggerView.filter.uncheckAll=Deseleziona tutte le categorie
 LoggerView.filter.checkAll=Seleziona tutte le categorie
-LoggerView.loggingDisabled=Il log non \u00e8 attivo.
+LoggerView.loggingDisabled=La registrazione delle operazioni non \u00e8 attiva.
 LoggerView.includeOnly=Mostra solo le linee conformi a questa espressione regolare:
 LoggerView.excludeAll=Nascondi le linee conformi a questa espressione regolare:
 ConfigView.section.logging.log0type=Informazioni
 ConfigView.section.logging.log1type=Avviso
 ConfigView.section.logging.log2type=Errore
-ConfigView.section.logging.filter=Filtra durante il log nel file
-ConfigView.section.logging.level=Livello di log
-ConfigView.section.logging.showLogsFor=Mostra il log %1 per le seguenti categorie:
+ConfigView.section.logging.filter=Filtra durante la registrazione nel file
+ConfigView.section.logging.level=Livello di registrazione
+ConfigView.section.logging.showLogsFor=Mostra il registro %1 per le categorie seguenti:
 ConfigView.pluginlist.column.loadAtStartup=Carica all'avvio
 ConfigView.pluginlist.column.type=Tipo
 ConfigView.pluginlist.column.type.perUser=Per utente
@@ -1697,10 +1695,10 @@ ConfigView.section.connection.encryption.min_encryption_level.tooltip=In chiaro
 Peers.column.Encryption=Cifratura
 Peers.column.Encryption.info=Livello di cifratura in uso
 ConfigView.section.connection.encryption.encrypt.info=Con la cifratura attiva non ci si pu\u00f2 connettere ai client incompatibili se non si abilitano le impostazioni alternative.
-ConfigView.section.connection.encryption.encrypt.info.link=Visitare questo collegamento per ulteriori informazioni
-MainWindow.sr.status.tooltip.ok=Rapporto di condivisione OK: \u00ab%1\u00bb
-MainWindow.sr.status.tooltip.poor=Rapporto di condivisione scarso: \u00ab%1\u00bb < 0.9
-MainWindow.sr.status.tooltip.bad=Rapporto di condivisione pessimo: \u00ab%1\u00bb < 0.5
+ConfigView.section.connection.encryption.encrypt.info.link=Ulteriori informazioni (in inglese)
+MainWindow.sr.status.tooltip.ok=Rapporto di condivisione OK: %1
+MainWindow.sr.status.tooltip.poor=Rapporto di condivisione scarso: %1 < 0.9
+MainWindow.sr.status.tooltip.bad=Rapporto di condivisione pessimo: %1 < 0.5
 ConfigView.section.style.status=Barra di stato:
 ConfigView.section.style.status.show_sr=Rapporto di condivisione
 ConfigView.section.style.status.show_nat=Stato NAT
@@ -1725,7 +1723,7 @@ TorrentOptionsView.param.max.uploads=Numero massimo di slot di upload [minimo: 2
 MyTorrentsView.dialog.setPosition.title=Impostazione della posizione
 MyTorrentsView.dialog.setPosition.text=Inserire la posizione da attribuire ai torrent selezionati:
 MyTorrentsView.menu.reposition.manual=Riposiziona..
-ConfigView.section.connection.advanced.info.link=Visitare questo link per ulteriori informazioni
+ConfigView.section.connection.advanced.info.link=Ulteriori informazioni (in inglese)
 ConfigView.section.connection.advanced.socket.group=Impostazioni del socket
 ConfigView.section.connection.advanced.bind_port=Associa alla porta locale [0: disattivato]
 ConfigView.section.connection.advanced.bind_port.tooltip=Le connessioni socket uscenti saranno associate localmente alla porta stabilita.\nAbilitarlo potrebbe aiutare in caso di problemi di instabilit\u00e0 NAT del router.
@@ -1737,7 +1735,7 @@ ConfigView.label.maxuploadsseeding=Valore alternativo quando solo in seed
 MyTorrentsView.filter=Filtra:
 popup.error.hideall=Nascondi tutto
 ConfigView.section.style.dataStatsOnly=Mostra soltanto le statistiche dei dati (nascondi le statistiche del protocollo)
-ConfigView.section.style.separateProtDataStats=Mostra separatamente le statistiche delle informazioni e del protocollo come \u00abinformazioni (protocollo)\u00bb
+ConfigView.section.style.separateProtDataStats=Mostra separatamente le statistiche dei dati e del protocollo come \u00abdati (protocollo)\u00bb
 MyTorrentsView.dialog.setFilter.title=Modifica del filtro
 MyTorrentsView.dialog.setFilter.text=La sezione %1 sar\u00e0 filtrata attraverso il testo specificato sotto. Usare il simbolo | (pipe) per filtrare usando pi\u00f9 frasi.
 MyTorrentsView.filter.tooltip=Premere Ctrl+X per passare dal RegEx alla normale modalit\u00e0 di ricerca.\nUsare il simbolo | (pipe) per filtrare usando pi\u00f9 frasi.
@@ -1755,7 +1753,7 @@ Plugin.localtracker.autoadd.info=Aggiungi automaticamente questi peer locali [in
 Plugin.localtracker.autoadd=Peer espliciti
 Plugin.localtracker.networks.info=Considera locali le seguenti reti [reti separate da \u00ab;\u00bb, ad esempio 145.227.*.*]
 Plugin.localtracker.networks=Reti locali
-MainWindow.menu.view.plugins.logViews=Viste log
+MainWindow.menu.view.plugins.logViews=Registro delle operazioni
 SpeedView.stats.autospeed=Velocit\u00e0 di upload automatica
 SpeedView.stats.autospeed.disabled=Questa caratteristica o \u00e8 disabilitata (ha bisogno del DHT) o non \u00e8 in uso (\u00e8 stata scelta manualmente una velocit\u00e0 di upload)
 SpeedView.stats.idlePing=Ping quando inattivo:
@@ -1830,8 +1828,8 @@ ConfigView.label.tcplistenport=Porta in ascolto TCP in entrata
 ConfigView.label.udplistenport=Porta in ascolto UDP
 upnp.portchange.alert=Le seguenti porte sono state cambiate per evitare problemi con dispositivi UPnP: %1 [vecchia porta=%2] %3 [vecchia porta=%4]
 ConfigView.section.proxy.username.info=Se il proxy richiede l'autenticazione anche quando non \u00e8 definita, usare la stringa \u00ab<none>\u00bb come nome utente.
-ConfigView.label.maxuploadswhenbusymin=Timer per la massima velocit\u00e0 di upload per torrent quando la velocit\u00e0 di upload globale supera il limite (sec)
-MainWindow.menu.help.debug=Genera informazioni di debug (log del crash)
+ConfigView.label.maxuploadswhenbusymin=Ritardo per la modifica della velocit\u00e0 massima di upload dei torrent quando la velocit\u00e0 di upload globale supera il limite (sec)
+MainWindow.menu.help.debug=Genera informazioni di debug (registro del crash)
 DownloadManager.error.badsize=Dimensione non corretta
 natpmp.info=NAT-PMP \u00e8 l'alternativa per Apple a UPnP ed \u00e8 supportato dalle recenti stazioni Airport.\n\nNota che al momento UPnP dev'essere abilitato per poter abilitare NAT-PMP, in quanto la periferica NAT-PMP \u00e8 trattata come un particolare tipo di periferica UPnP.
 natpmp.enable=Abilita (nota: dev'essere abilitato anche nella configurazione del router Airport per funzionare)
@@ -1879,16 +1877,9 @@ MainWindow.menu.view.iconbar=Barra degli strumenti
 MyTorrentsView.menu.rename=Rinomina
 MyTorrentsView.menu.rename.displayed=Cambia il nome visualizzato
 MyTorrentsView.menu.rename.save_path=Cambia il percorso di salvataggio
-MyTorrentsView.menu.rename.displayed_and_save_path=Cambia entrambi
-MyTorrentsView.menu.rename.displayed.enter.title=Modifica del nome visualizzato
-MyTorrentsView.menu.rename.displayed.enter.message=Inserire il nuovo nome da visualizzare per questo download.
-MyTorrentsView.menu.rename.displayed.enter.message.2=Se non si inserisce nulla, sar\u00e0 utilizzato il nome originale.
-MyTorrentsView.menu.rename.save_path.enter.title=Modifica del percorso di salvataggio
-MyTorrentsView.menu.rename.save_path.enter.message=Inserire il nuovo percorso di salvataggio per questo download.
-MyTorrentsView.menu.rename.save_path.enter.message.2=Se non si inserisce nulla, sar\u00e0 utilizzato il nome visualizzato del download.
-MyTorrentsView.menu.rename.displayed_and_save_path.enter.title=Rinominazione del download
-MyTorrentsView.menu.rename.displayed_and_save_path.enter.message=Inserire il nuovo nome per questo download.
-MyTorrentsView.menu.rename.displayed_and_save_path.enter.message.2=Se non si inserisce nulla, sar\u00e0 utilizzato il valore originale.
+AdvRenameWindow.title=Rinominazione del torrent
+AdvRenameWindow.message=Inserire un nuovo nome per questo download.
+AdvRenameWindow.rename.torrent=Rinomina torrent
 MyTorrentsView.menu.edit_comment=Modifica commento
 MyTorrentsView.menu.edit_comment.enter.title=Modifica del commento
 MyTorrentsView.menu.edit_comment.enter.message=Inserire un commento per questo download.
@@ -1903,9 +1894,9 @@ authenticator.savepassword=Ricorda la password
 ConfigView.section.security.clearpasswords=Cancella le password memorizzate
 ConfigView.section.security.clearpasswords.button=Cancella
 Content.alert.notuploaded.title=Invio non completo
-Content.alert.notuploaded.text=L'invio di \u00ab%1\u00bb non \u00e8 completo. Se si decide di %2 ora, gli altri utenti non saranno in grado di scaricare completamente i contenuti pubblicati.\n\nSi \u00e8 sicuri di voler %2?
+Content.alert.notuploaded.text=L'invio di \u00ab%1\u00bb non \u00e8 completo. Se si decide di %2 ora, gli altri utenti non saranno in grado di scaricare completamente i contenuti multimediali pubblicati.\n\nSi \u00e8 sicuri di voler %2?
 Content.alert.notuploaded.multi.title=Upload non completi
-Content.alert.notuploaded.multi.text=%1 dei contenuti pubblicati non sono stati interamente inviati. Se si decide di %2 ora, gli altri utenti non saranno in grado di scaricare completamente i contenuti pubblicati. Si \u00e8 sicuri di voler %2?\n\nContenuti non interamente pubblicati:\n%3
+Content.alert.notuploaded.multi.text=%1 dei contenuti multimediali pubblicati non sono stati interamente inviati. Se si decide di %2 ora, gli altri utenti non saranno in grado di scaricare completamente i contenuti multimediali pubblicati. Si \u00e8 sicuri di voler %2?\n\nContenuti multimediali non interamente pubblicati:\n%3
 Content.alert.notuploaded.stop=ferma
 Content.alert.notuploaded.quit=chiude Vuze
 TorrentInfoView.torrent.encoding=Codifica del torrent
@@ -1913,18 +1904,18 @@ TorrentInfoView.columns=Colonne dalla vista \u00abI miei torrent\u00bb
 progress.window.title=Operazioni in corso
 progress.window.msg.filemove=Attendere il completamento dell'operazione di spostamento/rinomina.
 ConfigView.label.popup.timestamp=Aggiungi l'ora agli avvisi a comparsa
-ConfigView.label.popup.autohide=Nascondi automaticamente gli avvisi non contenenti errori dopo n secondi (imposta a 0 per disabilitare la funzione)
+ConfigView.label.popup.autohide=Nascondi automaticamente gli avvisi che non contengono errori dopo n secondi (imposta a 0 per disabilitare la funzione)
 ConfigView.label.popup.suppress_alerts=Disabilita gli avvisi
 ConfigView.label.popup.use_message_boxes=Usa finestre di dialogo invece degli avvisi a comparsa.
 ConfigView.label.popup.show=Mostra tutti gli avvisi a comparsa registrati fino a questo punto (se ce ne sono)
 ConfigView.label.popup.show.button=Mostra
-ConfigView.label.please.visit.here=Visitare questo collegamento per ulteriori informazioni.
+ConfigView.label.please.visit.here=Ulteriori informazioni (in inglese)
 ConfigView.section.ipfilter.enable.descriptionCache=Conserva le descrizioni degli IP nello scratch file
 ConfigView.section.ipfilter.enable.descriptionCache.tooltip=Se disabilitata, le descrizioni non saranno memorizzate
 OpenTorrentWindow.filesInfo=Saranno scaricati %1 di %2.
 OpenTorrentWindow.diskUsage=%1 di %2
 ConfigView.label.openmytorrents=Apri \u00abI miei torrent\u00bb all'avvio
-ConfigView.label.open_transfer_bar_on_start=Apri la barra di trasferimento all'avvio
+ConfigView.label.open_transfer_bar_on_start=Apri la barra dei trasferimenti all'avvio
 ConfigView.section.style.DNDalwaysInIncomplete=Mostra sempre i torrent parzialmente completi (contenenti file da \u00abNon Scaricare\u00bb) nella sezione \u00abIncompleti\u00bb di \u00abI miei torrent\u00bb
 OpenTorrentWindow.mb.noGlobalDestDir.title=Cartella di destinazione non valida
 OpenTorrentWindow.mb.noGlobalDestDir.text=La cartella di destinazione \u00ab%1\u00bb non \u00e8 valida.
@@ -1964,6 +1955,8 @@ ConfigView.label.closetotray._mac=Il pulsante \u00abChiudi\u00bb minimizza sull'
 ConfigView.label.minimizetotray._mac=Il pulsante \u00abRiduci a icona\u00bb minimizza sull'icona della Barra di stato
 OpenTorrentWindow.mb.existingFiles.title=File gi\u00e0 esistenti!
 OpenTorrentWindow.mb.existingFiles.text=Alcuni dei file esistono gi\u00e0 delle cartelle di destinazione specificate:\n\n%1\nSe si continua, Vuze controller\u00e0 se quei file contengono dati corretti e li sovrascriver\u00e0 se necessario.
+splash.unloadingTorrents=Unload dei torrent in corso
+splash.unloadingTorrent=Unload del torrent in corso
 ConfigView.section.file.defaultdir.autorename=Rinomina automaticamente i dati del torrent se i file nel percorso sembrano diversi
 ConfigView.section.file.defaultdir.autorename.tooltip=Impedisce a un torrent di sovrascrivere i file di un altro torrent quando i nomi coicidono
 alert.raised.at.close=(Messaggio dall'ultima chiusura di Vuze)
@@ -1973,7 +1966,7 @@ Peers.column.maxupspeed=Max UP
 Peers.column.maxdownspeed=Max DL
 MyTorrents.items.DownSpeedLimit.disabled=Nessun download
 upnp.selectedaddresses=Indirizzi (separati da \u00ab;\u00bb, il prefisso \u00ab-\u00bb significa nega, \u00ab+\u00bb significa consente) [vuoto: qualsiasi]
-upnp.alert.multipledevice.warning=Sono state rilevate pi\u00f9 periferiche UPnP. Controllare se tutte richiedono il mappaggio delle porte (vedere il log UPnP e la configurazione).
+upnp.alert.multipledevice.warning=Sono state rilevate pi\u00f9 periferiche UPnP. Controllare se tutte richiedono la mappatura delle porte (vedere il registro delle informazioni di UPnP e la configurazione).
 UpdateMonitor.messagebox.restart.title=Aggiornamento del software
 UpdateMonitor.messagebox.restart.text=Vuze ha appena completato il download di un importante aggiornamento e dev'essere riavviato affinch\u00e9 l'aggiornamento possa essere installato.
 PiecesView.BlockView.Have=Blocchi posseduti
@@ -1988,17 +1981,17 @@ Peers.column.handshake_reserved=Byte riservati per l'handshake
 Peers.column.handshake_reserved.info=Indica quali bit riservati sono stati impostati nell'handshake BitTorrent.
 Peers.column.client_identification=Identificazione del client
 Peers.column.client_identification.info=Indica i nomi base dei client riportati ad Vuze - utile per il debug.
-dht.warn.user=Avvisa in caso di potenziali problemi di NAT/mappaggio di porte
+dht.warn.user=Avvisa in caso di potenziali problemi di NAT/mappatura di porte
 ConfigView.label.openbar.incomplete=Barre di progesso: apri in automatico per i download
 ConfigView.label.openbar.complete=apri in automatico per i seed
 ConfigView.label.transferbar.remember_location=Ricorda l'ultima posizione delle barre di trasferimento
-ConfigView.section.transfer.autospeed.forcemin=Forza questa velocit\u00e0 di upload quando si sta stabilendo la connessione (%1)
-MainWindow.menu.tools.speedtest=Test di velocit\u00e0...
-speedtest.wizard.title=Test di velocit\u00e0
-speedtest.wizard.run=Esegui un test di velocit\u00e0
+ConfigView.section.transfer.autospeed.forcemin=Forza questa velocit\u00e0 di upload mentre si stabilisce la connessione (%1)
+MainWindow.menu.tools.speedtest=Test della velocit\u00e0...
+speedtest.wizard.title=Test della velocit\u00e0
+speedtest.wizard.run=Esegui un test della velocit\u00e0
 speedtest.wizard.test.mode.updown=upload e download
 SpeedTestWizard.test.panel.currinfo=Test di banda BitTorrent.
-SpeedTestWizard.test.panel.label=Test di velocit\u00e0 di Vuze:
+SpeedTestWizard.test.panel.label=Test della velocit\u00e0 di Vuze:
 SpeedTestWizard.test.panel.already.running=Test gi\u00e0 in esecuzione!
 SpeedTestWizard.test.panel.not.accepted=Richiesta del test non accettata:
 SpeedTestWizard.test.panel.abort=Annulla
@@ -2006,13 +1999,13 @@ SpeedTestWizard.test.panel.abort.countdown=Il test sar\u00e0 annullato in:
 SpeedTestWizard.test.panel.test.countdown=Il test terminer\u00e0 in:
 SpeedTestWizard.test.panel.testfailed=Test non riuscito
 SpeedTestWizard.test.panel.aborted=Test annullato manualmente.
-SpeedTestWizard.test.panel.enc.label=Premere per effettuare il test usando la cifratura:
+SpeedTestWizard.test.panel.enc.label=Premere per la cifratura:
 SpeedTestWizard.test.panel.encrypted=cifrato
 SpeedTestWizard.set.upload.button.apply=Applica
 SpeedTestWizard.set.upload.result=Risultati dell'ultimo test
 SpeedTestWizard.set.upload.bytes.per.sec=KB/s
 SpeedTestWizard.set.upload.bits.per.sec=bit/s
-SpeedTestWizard.finish.panel.title=Test di velocit\u00e0 terminato!
+SpeedTestWizard.finish.panel.title=Test della velocit\u00e0 terminato!
 SpeedTestWizard.finish.panel.click.close=Test della velocit\u00e0 completato. Fare clic su Chiudi per uscire.
 SpeedTestWizard.finish.panel.max.seeding.upload=Max upload durante il seed :
 SpeedTestWizard.finish.panel.enabled=abilitato
@@ -2035,13 +2028,13 @@ SpeedTestWizard.stage.message.starting=avvio test...
 SpeedTestWizard.stage.message.connect.stats=Statistiche di connessione: peer=%1, down_ok=%2, up_ok=%3
 window.uiswitcher.title=Selettore di interfaccia di Vuze
 window.uiswitcher.text=Scegliere l'interfaccia utente che meglio si adatta alle proprie esigenze tra quelle elencate di seguito.
-window.uiswitcher.NewUI.text=* Raccomandata per i principianti e i nuovi utenti.\n\n* Un'interfaccia grafica semplice e intuitiva\n\n* Necessaria per pubblicare contenuti sulla piattaforma Vuze
+window.uiswitcher.NewUI.text=* Raccomandata per i principianti e i nuovi utenti.\n\n* Un'interfaccia grafica semplice e intuitiva\n\n* Necessaria per pubblicare contenuti multimediali nella piattaforma Vuze
 window.uiswitcher.ClassicUI.title=Interfaccia classica
-window.uiswitcher.ClassicUI.text=* Mantiene le funzionalit\u00e0 dei client della serie 2.x\n\n* Il modulo per i contenuti Vuze non sar\u00e0 caricato
+window.uiswitcher.ClassicUI.text=* Mantiene le funzionalit\u00e0 dei client della serie 2.x\n\n* Il modulo per i contenuti multimediali di Vuze non sar\u00e0 caricato
 window.uiswitcher.bottom.text=Si pu\u00f2 cambiare facilmente la scelta con il pulsante Selettore di interfaccia di Vuze.
 iconBar.switch.tooltip=Selettore di interfaccia di Vuze
 VivaldiView.notAvailable=Vista Vivaldi non disponibile
-restart.error=Riavvio non riuscito:\n%1\nVisitare <A HREF="{restart.error.url}">restarting issues</a> (in inglese).
+restart.error=Riavvio non riuscito:\n%1\nVedere <A HREF="{restart.error.url}">restarting issues</a> (in inglese) per maggiori informazioni.
 restart.error.oom=Memoria insufficiente
 restart.error.fnf=\u00ab%1\u00bb non trovato in \u00ab%2\u00bb
 restart.error.pnf=Percorso \u00ab%1\u00bb non trovato
@@ -2050,7 +2043,7 @@ restart.error.denied=Accesso negato nel tentativo di eseguire \u00ab%1\u00bb. As
 TableColumn.header.date_completed=Completato il
 TableColumn.menu.date_added.reset=Resetta la data
 ConfigView.section.ipfilter.discardbanning=Blocca i peer il cui rapporto dati danneggiati/integri supera [0: disabilitato]
-ConfigView.section.ipfilter.discardminkb=Almeno %1 di dati danneggiati prima di applicare il rapporto scelto
+ConfigView.section.ipfilter.discardminkb=Applica il rapporto dopo aver scaricato questa quantit\u00e0 di dati danneggiati (%1)
 ConfigView.interface.start.advanced=Avvia con l'interfaccia avanzata (AZ 2.x)
 MyTorrents.column.ColumnQuality=Qualit\u00e0
 MyTorrents.column.ColumnSpeed=Velocit\u00e0
@@ -2082,6 +2075,7 @@ v3.MainWindow.menu.advanced=&Avanzate
 v3.MainWindow.menu.view.searchbar=Barra di Ricerca
 v3.MainWindow.menu.view.tabbar=Barra dei Tab
 v3.MainWindow.currentDL=In download
+v3.MainWindow.button.stream=Fai lo stream
 v3.MainWindow.button.stop=Ferma
 v3.MainWindow.button.start=Avvia
 v3.MainWindow.button.pause=Pausa
@@ -2091,20 +2085,19 @@ v3.MainWindow.button.comment=Commento
 v3.MainWindow.button.viewdetails=Vedi dettagli
 v3.MainWindow.button.play=Riproduci
 v3.MainWindow.button.cancel=Annulla
-v3.MainWindow.button.sendtofriend=Condividi torrent
 v3.MainWindow.button.preview=Anteprima
 v3.MainWindow.view.wait=Inizializzazione dell'interfaccia, attendere.
 v3.MainWindow.xofx=%1 di %2
 v3.MainWindow.Loading=Caricamento in corso... attendere
 v3.filter-bar=Filtro Titolo:
 v3.MainWindow.search.defaultText=cerca...
-v3.mb.delPublished.title=Smetti il seed del contenuto
-v3.mb.delPublished.text=ATTENZIONE: Questa azione NON rimuover\u00e0 il contenuto pubblicato \u00ab%1\u00bb da <A HREF="%2">%3</A>.\n\nFare clic su \u00abElimina\u00bb solo se si vuole che rimanga pubblicato e scaricabile, ma si vuole liberare la banda. Assicurarsi che il processo di upload sia stato completato prima di farlo (<A HREF="%4">come</A>?).\n\nFare clic su \u00abRimuovi\u00bb se si vuole rimuovere completamente il contenuto pubblicato da %3, e usare il pulsante (X) del pannello Contenuto pubblicato nel tab Pubblica.\n\n<A HREF="%4">Ulteriori informazioni</A>.\n\n
+v3.mb.delPublished.title=Smetti di fare il seed del contenuto multimediale
+v3.mb.delPublished.text=ATTENZIONE: Questa azione NON rimuover\u00e0 il contenuto multimediale \u00ab%1\u00bb pubblicato da <A HREF="%2">%3</A>.\n\nFare clic su \u00abElimina\u00bb solo se si vuole che rimanga pubblicato e scaricabile, ma si vuole liberare la banda. Assicurarsi che il processo di upload sia stato completato prima di farlo (<A HREF="%4">come</A>?).\n\nFare clic su \u00abRimuovi\u00bb se si vuole rimuovere completamente da %3 il contenuto multimediale pubblicato, e usare il pulsante (X) del pannello Contenuto pubblicato nel tab Pubblica.\n\n<A HREF="%4">Ulteriori informazioni</A>.\n\n
 v3.mb.delPublished.delete=&Elimina
 v3.mb.delPublished.cancel=&Rimuovi
 v3.mb.openFile.title=Apri file
-v3.mb.openFile.text.known=Questo contenuto non \u00e8 correntemente supportato dal riproduttore di Vuze. Visitare la <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Playback guide</a> (in inglese) creata dalla comunit\u00e0 per maggiori informazioni.\n\nIl tipo del file sembra essere: %2 (%3)\n
-v3.mb.openFile.text.unknown=Questo contenuto non \u00e8 correntemente supportato dal riproduttore di Vuze. Visitare la <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Playback guide</a> (in inglese) creata dalla comunit\u00e0 per maggiori informazioni.\n\nEstensione del file: %2\n
+v3.mb.openFile.text.known=Questo contenuto multimediale non \u00e8 correntemente supportato dal riproduttore di Vuze. Visitare la <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Playback guide</a> (in inglese) creata dalla comunit\u00e0 per maggiori informazioni.\n\nIl tipo del file sembra essere: %2 (%3)\n
+v3.mb.openFile.text.unknown=Questo contenuto multimediale non \u00e8 correntemente supportato dal riproduttore di Vuze. Visitare la <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Playback guide</a> (in inglese) creata dalla comunit\u00e0 per maggiori informazioni.\n\nEstensione del file: %2\n
 v3.mb.openFile.button.play=Riproduci
 v3.mb.openFile.button.cancel=Annulla
 v3.mb.openFile.button.guide=Leggi la guida alla riproduzione
@@ -2114,8 +2107,8 @@ v3.mb.PlayFileNotFound.text=I file per \u00ab%1\u00bb sono stati cancellati o so
 v3.mb.PlayFileNotFound.button.remove=Rimuovi da Vuze
 v3.mb.PlayFileNotFound.button.redownload=Scarica di nuovo
 v3.mb.PlayFileNotFound.button.find=Trova manualmente..
-v3.mb.deletePurchased.title=Rimozione di contenuti acquistati
-v3.mb.deletePurchased.text=Eliminare \u00ab%1\u00bb?\n\nQuesto \u00e8 contenuto acquistato, o per il quale era richiesto l'accesso per poter effettuare il download.
+v3.mb.deletePurchased.title=Rimozione di contenuti multimediali acquistati
+v3.mb.deletePurchased.text=Eliminare \u00ab%1\u00bb?\n\nQuesto \u00e8 un contenuto multimediale acquistato, o per il quale era richiesto l'accesso per poter effettuare il download.
 v3.mb.deletePurchased.button.delete=&Elimina
 v3.mb.deletePurchased.button.cancel=&Annulla
 v3.topbar.menu.show.plugin=Area plugin
@@ -2158,7 +2151,7 @@ ConfigView.section.transfer.autospeed.resetnetwork=Ripristina dettagli rete
 ConfigView.section.transfer.autospeed.network.info=I limiti in alto di norma sono calcolati automaticamente durante il download o come risultato di un test di velocit\u00e0. Se si vuole specificarli manualmente, si devono usare le opzioni in basso.\nTutti i limiti eccetto quelli \u00abFissi\u00bb saranno regolati automaticamente in caso di necessit\u00e0. \nInserire il valore e scegliere il suo tipo. Notare che le velocit\u00e0 sono espresse in %1.
 dialog.uiswitcher.restart.title=Selettore di interfaccia: riavvio di Vuze necessario
 dialog.uiswitcher.restart.text=Per cambiare l'interfaccia utente \u00e8 nesessario riavviare Vuze.
-TrayWindow.menu.close=Chiudi il cestino dei download
+TrayWindow.menu.close=Chiudi il cesto dei download
 # Used for peers which we can't determine.
 PeerSocket.unknown=Sconosciuto
 PeerSocket.bad_peer_id=peer ID non valido
@@ -2203,7 +2196,7 @@ Content.alert.notuploaded.button.abort=&Non uscire
 ConfigView.label.checkOnSeeding=Esegui ricontrollo delle parti a basso consumo di risorse se in seed
 ConfigView.label.ui_switcher=Mostra il selettore di interfaccia di Vuze
 ConfigView.label.ui_switcher_button=Mostra
-SpeedTestWizard.test.panel.explain=Misura la velocit\u00e0 del protocollo BT del client Vuze. Scegliere il tipo di test di velocit\u00e0 e la modalit\u00e0 di cifratura. Visitare la pagina del wiki di Vuze per dettagli su questo test. Il test sar\u00e0 interrotto automaticamente nel caso richieda pi\u00f9 di due minuti. Normalmente il test termina in meno di un minuto.
+SpeedTestWizard.test.panel.explain=Misura la velocit\u00e0 del protocollo del client Vuze. Scegliere il tipo di test di velocit\u00e0 e la modalit\u00e0 di cifratura. Visitare la pagina del wiki di Vuze per dettagli su questo test. Il test sar\u00e0 interrotto automaticamente nel caso richieda pi\u00f9 di due minuti. Normalmente il test dura meno di un minuto.
 SpeedTestWizard.set.upload.hint=Impostare i limiti di upload e download usati dall'algoritmo Auto-speed di Vuze.
 SpeedTestWizard.set.upload.panel.explain=I limiti qui impostati sono usati dall'algoritmo Auto-speed di Vuze. Impostare i limiti di trasferimento e di confidenza.\n\nNotare che spesso le velocit\u00e0 delle linee spesso sono espresse in \u00abbit per secondo\u00bb, mentre il valore mostrato qui sotto \u00e8 in \u00abkilobyte per secondo\u00bb.
 SpeedTestWizard.set.limit.conf.level=Confidenza
@@ -2237,7 +2230,7 @@ GeneralView.yes=S\u00ec
 ConfigView.label.userequestlimiting=Per limitare la velocit\u00e0 di download, limita le richieste invece di usare le letture ritardate [non ha effetto quando la velocit\u00e0 di download \u00e8 illimitata]
 ConfigView.label.userequestlimiting.tooltip=La limitazione delle richieste \u00e8 un metodo pi\u00f9 rozzo rispetto alle letture ritardate, ma permette di gestire la priorit\u00e0 dei download in base alla posizione in coda e pu\u00f2 migliorare le prestazioni della rete
 ConfigView.label.userequestlimitingpriorities=Concentra la velocit\u00e0 di download sui torrent in cima alla coda quando viene raggiunto il limite di velocit\u00e0 di download
-ConfigView.section.logging.timestamp=Applica formato data ai file di log
+ConfigView.section.logging.timestamp=Applica formato della data ai file di registro
 Peers.column.timetocomplete=Tempo rimanente
 Peers.column.timetocomplete.info=Tempo rimanente al completamento per il peer
 ConfigView.section.interface.display.suppress.file.download.dialog=Disabilita l'avviso a comparsa per i download
@@ -2366,6 +2359,7 @@ Button.retry=&Riprova
 Button.ignore=&Ignora
 azbuddy.ui.table.msg_in=Mess. in ingresso
 azbuddy.ui.table.msg_out=Mess. in uscita
+v3.MainWindow.menu.view.footer=Riquadro in basso
 azbuddy.downspeed=Velocit\u00e0 massima di download per gli amici (KB/s) [0: unlimited]
 security.crypto.badpw=La password inserita \u00e8 errata.
 ConfigView.section.security.backupkeys=Fai il backup delle chiavi in un file
@@ -2385,93 +2379,37 @@ Button.bar.share=Condividi
 Button.bar.add=Aggiungi
 Button.bar.edit=Modifica
 Button.bar.edit.cancel=Modifica eseguita
-v3.Share.menu=Condividi contenuti
-v3.Share.header=Condividi
-v3.Share.header.message=Condividi con gli amici attuali, o aggiungi nuovi amici.
-v3.Share.add.buddy=Aggiungi amici
-v3.Share.add.edit.buddy=Aggiungi/Modifica gli amici
-v3.Share.add.buddy.all=Condividi con tutti
-v3.Share.add.buddy.existing=Amici esistenti:
-v3.Share.add.buddy.new=Nuovi amici:
-v3.Share.buddies=Amici
-v3.Share.invitees=Invitati
-v3.Share.invite.buddies.prompt=Invita altri amici con cui condividere
-v3.Share.send.now=Invia
-v3.Share.optional.message=Messaggio opzionale inviato come notifica (massimo 140 caratteri):
-v3.Share.disclaimer=Nota: sia il contenuto condiviso sia questo messaggio saranno criptati.
-v3.Share.disclaimer.link=Maggiori informazioni
-ConfigView.section.security.vuze.login=\u00c8 necessario effettuare l'accesso a Vuze per usare questa funzione
-v3.buddy.menu.viewprofile=Visualizza profilo
-v3.buddy.menu.remove=Rimuovi amico
 v3.MainWindow.menu.view.pluginbar=Barra dei plugin
-v3.MainWindow.menu.view.buddies-viewer=Barra degli amici
-v3.activity.buddy-request=\u00c8 presente una richiesta di amicizia da %1.
-v3.activity.buddy-request.accept=Accetta
-v3.activity.buddy-request.multi=\u00c8 presente una richiesta di amicizia (n\u00b0%3) da %1.
-v3.activity.buddy-linkup=Si \u00e8 ora amici di %1.
-v3.activity.share-content=%1 ha condiviso %2 con te. %3 <A HREF="%4" TITLE="%5">dice...</A>
-v3.activity.share-content.no-msg=%1 ha condiviso %2 con te
-v3.buddies.friends=Amici
-v3.buddies.online=In linea (%1)
-v3.buddies.remove=Rimuovi amico
-v3.buddies.add.to.share=Aggiungi amico alla condivisione
 MainWindow.dialog.select.vuze.file=Selezione di un file Vuze
 MainWindow.menu.file.open.vuze=File Vuze...
-azbuddy.ui.dialog.disable.title=Disabilitazione del plugin Amici
-azbuddy.ui.dialog.disable.text=La disabilitazione del plugin Amici impedir\u00e0 di condividere torrent usando la barra degli amici nella parte bassa della finestra e di modificare la lista degli amici.\n\nDisabilitare gli amici?
 metasearch.addtemplate.title=Conferma installazione del template di ricerca
 metasearch.addtemplate.desc=Installare il template di ricerca \u00ab%1\u00bb?
 v3.share.private.title=Condivisione di torrent
 v3.share.private.text=Il torrent selezionato \u00e8 marcato come privato.\n\nNon si possono condividere i torrent privati.
-v3.buddies.disabled.title=Plugin degli amici disabilitato
-v3.buddies.disabled.text._windows=Il plugin degli amici \u00e8 stato disabilitato, impedendo di poter condividere o accettare torrent o richieste di amicizia. Si possono cambiare le impostazoni nella finestra Opzioni.
-v3.buddies.disabled.text._mac=Il plugin degli amici \u00e8 stato disabilitato, impedendo di poter condividere o accettare torrent o richieste di amicizia. Si possono cambiare le impostazoni nella finestra Configurazione.
 metasearch.addtemplate.dup.title=Template gi\u00e0 installato
 metasearch.addtemplate.dup.desc=Il template di ricerca %1 \u00e8 gia installato.
 metasearch.export.select.template.file=Salva template
 metasearch.import.select.template.file=Apri template
-v3.MainWindow.button.newtag.share=Nuovo! Condividi il torrent
-v3.buddies.faq=Maggiori informazioni
 dialog.uiswitch.title=Usa l'interfaccia Vuze
 dialog.uiswitch.text=\u00c8 necessario usare l'interfaccia Vuze per usare questa funzione.\n\n\u00c8 necessario riavviare Vuze.
 dialog.uiswitch.button=Usa l'interfaccia Vuze
-azbuddy.tracker.enabled=Abilitare l'\u00abAccelerazione degli amici\u00bb per dare priorit\u00e0 agli scaricamenti degli amici
+azbuddy.tracker.enabled=Abilitare l'\u00abAccelerazione degli amici\u00bb per dare priorit\u00e0 ai download degli amici.
 azbuddy.protocolspeed=Massima velocit\u00e0 per il protocollo relativo agli amici (KB/s)
 v3.MainWindow.button.run=Esegui il file scaricato
-v3.activity.header.friend.requests.foryou=Richieste di amicizia - ricevute
-v3.activity.header.friend.requests.fromyou=Richieste di amicizia - inviate
-v3.activity.header.friend.requests.accepted=Richieste di amicizia - accettate
-v3.activity.header.share.requests=Richieste di condivisione di torrent
 v3.activity.header.downloads=Download
-v3.activity.header.rating.reminders=Promemoria per le votazioni
 v3.activity.header.vuze.news=Notizie su Vuze
-login.optional.message=\u00c8 necessario aver eseguito l'accesso per usare questa funzione
-message.confirm.share.singular=Ottimo! La tua richiesta di condivisione di un torrent \u00e8 stata inviata.
-message.confirm.share.plural=Ottimo! Le tue richieste di condivisione di un torrent sono state inviate.
-message.confirm.share.invite.singular=Ottimo! La richiesta di connessione e condivisione \u00e8 stata inviata. Puoi dire all'amico di accettarla.
-message.confirm.share.invite.plural=Ottimo! Le richieste di connessione e condivisione sono state inviate. Puoi dire ai tuoi amici di accettarle.
-message.confirm.invite.singular=Ottimo! La richiesta di amicizia \u00e8 stata inviata. Puoi dire all'amico di accettarla.
-message.confirm.invite.plural=Ottimo! Le richieste di amicizia sono state inviate. Puoi dire ai tuoi amici di accettarle.
-message.confirm.invite.error=Ahi! C'\u00e8 stato un errore in questa richiesta. Sono presenti errori in uno o pi\u00f9 inviti.
-message.prompt.add.friends=Selezionare degli amici dalla barra laterale (in basso a sinistra)
 message.taking.too.long=L'operazione in corso sta prendendo pi\u00f9 tempo del previsto.\nPremere \u00abESC\u00bb per annullarla.
 message.status.success=Successo
-message.intro.friends=Aggiungi gli amici.\nCondividi i torrent.\nScarica pi\u00f9 velocemente.
 azbuddy.tracker.bbb.status.title=Accelerazione degli amici
 azbuddy.tracker.bbb.status.title.tooltip=Fare doppio clic per i dettagli
 azbuddy.tracker.bbb.status.idle=Nessuna accelerazione
 azbuddy.tracker.bbb.status.nli=Autenticazione richiesta
-azbuddy.tracker.bbb.status.in=Si sta venendo accelerati
+azbuddy.tracker.bbb.status.in=Si \u00e8 accelerati
 azbuddy.tracker.bbb.status.out=Amici che stanno accelerando il download
 v3.MainWindow.search.go.tooltip=Esegui ricerca
 v3.MainWindow.search.last.tooltip=Torna ai risultati di ricerca
-v3.activity.buddy-invited=La richiesta di amicizia \u00e8 stata inviata a %1.
-v3.activity.buddy-invited.multi=La richiesta di amicizia \u00e8 stata inviata a:\n%1
 metasearch.addtemplate.done.title=Template aggiunto
 metasearch.addtemplate.done.desc=Il template \u00ab%1\u00bb \u00e8 stato aggiunto con successo.\nSar\u00e0 usato nelle prossime ricerche.
-v3.MainWindow.button.share=Condividi contenuti
-v3.buddies.remove.buddy.dialog.title=Rimuovi
-v3.buddies.remove.buddy.dialog.text=Rimuovere l'amico %1?
 ConfigView.section.security.nopw=Nessuna password inserita
 ConfigView.section.security.nopw_v=Nessuna password disponibile, fare l'accesso a Vuze
 fileplugininstall.install.title=Installare il plugin?
@@ -2485,12 +2423,7 @@ azbuddy.os_not_avail=Non disponibile
 azbuddy.os_busy=Occupato
 azbuddy.os_offline=Non in linea
 azbuddy.ui.menu.disconnect=Disconnetti
-v3.chat.offline=%1 non \u00e8 in linea, ricever\u00e0 il messaggio quando torner\u00e0 disponibile.
-v3.chat.wrongversion=%1 usa una versione di Vuze che non supporta la chat.
 azbuddy.enable_chat_notif=Abilita le notifiche per la chat
-v3.buddies.dnd.info.dialog.title=Condivisione attraverso il trascinamento
-v3.buddies.dnd.info.dialog.text=\u00c8 stata inziata una condivisione attraverso il trascinamento. I contenuti stanno venendo preparati per la condivisione, e la schermata di condivisione verr\u00e0 aperta quando saranno pronti.\n\n\u00c8 necessario tenere aperto Vuze affinch\u00e9 l'amico riceva i contenuti.\n<A HREF="http://faq.vuze.com/?View=entry&EntryID=267">Ulteriori informazioni</A> (in inglese).
-v3.buddies.dnd.info.dialog.remember=Non visualizzare ancora questo messaggio
 progress.window.msg.progress=Attendere il completamento dell'operazione.
 ConfigView.section.connection.advanced.read_select=
 ConfigView.section.connection.advanced.read_select_min=Lettura: attesa minima (ms, valore predefinito %1)
@@ -2521,7 +2454,7 @@ iconBar.bottom=Sposta in basso
 iconBar.queue=Avvia
 iconBar.open=Aggiungi un torrent
 iconBar.share=Condividi
-iconBar.share.tooltip=Condividi contenuti
+iconBar.share.tooltip=Condividi contenuti multimediali
 iconBar.details=Dettagli
 iconBar.comment=Commento
 iconBar.play=Riproduci
@@ -2531,7 +2464,7 @@ v3.MainWindow.menu.view.actionbar=Barra delle azioni
 v3.MainWindow.menu.view.toolbars=Barre degli strumenti
 ump.install=Aggiornamento veloce in corso:\nSto installando un piccolo componente aggiuntivo necessario alla riproduzione di questo video.
 subscriptions.listwindow.title=Ricerca delle iscrizioni
-subscriptions.listwindow.autochecktext=Vuze pu\u00f2 trovare le iscrizioni relative ai contenuti nella Libreria. Abilitare questa funzione?
+subscriptions.listwindow.autochecktext=Vuze pu\u00f2 trovare le iscrizioni relative ai contenuti multimediali nella Libreria. Abilitare questa funzione?
 subscriptions.listwindow.loadingtext=Ricerca in corso delle iscrizioni relative a %1
 subscriptions.listwindow.failed=Nessuna iscrizione trovata
 subscriptions.listwindow.popularity=Popolarit\u00e0
@@ -2541,29 +2474,23 @@ subscriptions.listwindow.subscribe=Iscriviti
 TableColumn.header.azsubs.ui.column.subs=Iscriviti
 subscriptions.listwindow.popularity.reading=Ricevo...
 PluginDeprecation.log.start=Questa finestra contiene informazioni relative all'uso da parte dei plugin di funzionalit\u00e0 che saranno rimosse nelle versioni future di Vuze.\nNon \u00e8 necessario disinstallare il plugin, basta aggiornarlo all'ultima versione disponibile.\nSe si sta gi\u00e0 usando l'ultima versione disponibile, copiare il contenuto di questa finestra in un post del forum:\n \t%1\n\n
+PluginDeprecation.log.details=---------\nIDENTIFICATORE: %1\nCONTESTO: %2\n\n*** INIZIO TRACCIAMENTO ***\n%3*** FINE TRACCIAMENTO ***\n\n
 PluginDeprecation.view=Debug dei plugin
-PluginDeprecation.alert=Un plugin ha cercato di usare delle funzionalit\u00e0 che saranno rimosse in futuro - aprire il log di debug dei plugin per maggiori informazioni.
+PluginDeprecation.alert=Un plugin ha cercato di usare delle funzionalit\u00e0 che saranno rimosse in futuro - aprire il registro delle informazioni di debug dei plugin per maggiori informazioni.
 TableColumn.header.Thumbnail=Icona
-TableColumn.header.Thumbnail.info=L'icona per i contenuti Vuze; per gli altri contenuti sono icone del sistema operativo.
-TableColumn.header.Rating_global=Valutazione
-TableColumn.header.Rating_global.info=La valutazione globale per questo contenuto
+TableColumn.header.Thumbnail.info=L'icona per i contenuti multimediali di Vuze; per gli altri contenuti sono visualizzate le icone del sistema operativo.
 v3.MainWindow.menu.getting_started=&Per iniziare
 MainWindow.menu.community=&Comunit\u00e0
 MainWindow.menu.help.faq=Domande &frequenti (FAQ)
 MainWindow.menu.community.wiki=&Wiki della comunit\u00e0
 MainWindow.menu.community.forums=Fo&rum della comunit\u00e0
 MainWindow.menu.community.blog=&Blog di Vuze
-MainWindow.menu.community.add_friends=&Aggiungi amici
 MainWindow.menu.help.support=&Aiuto e supporto
 externalLogin.title=Accesso richiesto
 externalLogin.explanation=\u00c8 necessario eseguire l'accesso per il template \u00ab%1\u00bb. Una volta effettuato l'accesso, questa finestra si chiuder\u00e0 automaticamente. Se dovesse rimanere aperta, fare clic su \u00abFatto\u00bb.
 externalLogin.explanation.capture=\u00c8 necessario eseguire l'accesso per creare questo template. Dopo averlo fatto, fare clic su \u00abFatto\u00bb.
 Button.done=Fatto
 GeneralView.torrent_created_on_and_by=%1 di %2
-v3.Share.wizard.title=Assistente alla condivisione
-v3.AddFriends.header.message=Aggiungere amici per condividere i torrent preferiti
-v3.AddFriends.header=Aggiungi amici
-v3.AddFriends.wizard.title=Assistente all'aggiunta di amici
 Button.continue=Continua
 Button.preview=Anteprima
 Subscription.menu.forcecheck=Aggiorna ora
@@ -2574,9 +2501,6 @@ sidebar.LibraryDL=In download
 sidebar.LibraryCD=Completato
 authenticator.location=Posizione
 authenticator.details=Dettagli
-v3.MainWindow.menu.publish.new=Pubblica contenuti
-v3.MainWindow.menu.publish.mine=Contenuti pubblicati
-v3.MainWindow.menu.publish.about=Informazioni sulla pubblicazione...
 v3.MainWindow.menu.showActionBarText=Visualizza testo
 subscript.import.fail.title=Importazione non riuscita
 subscript.import.fail.desc=Settagli: %1
@@ -2585,9 +2509,9 @@ subscript.export.select.template.file=Salva iscrizione
 Button.remove=Rimuovi
 Button.send=Invia
 Button.back=Indietro
-sidebar.LibraryUnopened=Non visti
+sidebar.LibraryUnopened=Da vedere
 TableColumn.header.unopened=Nuovo
-Unopened.bigView.header=Nuovo
+Unopened.bigView.header=Nuovi
 Subscription.menu.deleteall=Elimina tutti i risultati
 Subscription.menu.reset=Ripristina lo stato iniziale
 ConfigView.section.Subscriptions=Iscrizioni
@@ -2611,7 +2535,7 @@ Button.save=Salva
 Button.add=Aggiungi
 Button.createNewSubscription=Nuova iscrizione
 Button.availableSubscriptions=Iscrizioni disponibili
-Wizard.Subscription.optin.description=Quando le iscrizioni sono abilitate, Vuze visualizzer\u00e0 le iscrizioni relative ai torrent nella libreria e avviser\u00e0 quando \u00e8 disponibile per il download un nuovo contenuto.\n\nAbilitare le iscrizioni?
+Wizard.Subscription.optin.description=Quando le iscrizioni sono abilitate, Vuze visualizzer\u00e0 le iscrizioni relative ai torrent nella libreria e avviser\u00e0 quando \u00e8 disponibile per il download un nuovo contenuto multimediale.\n\nAbilitare le iscrizioni?
 Wizard.Subscription.create.search=Cerca
 Wizard.Subscription.search.subtitle1=Digitare una ricerca per iniziare a creare l'iscrizione:
 Wizard.Subscription.search.subtitle2=Cosa posso cercare?
@@ -2619,13 +2543,11 @@ Wizard.Subscription.search.subtitle2.sub1=Film in HD, serie TV, film, trailer ne
 Wizard.Subscription.search.subtitle2.sub2=Torrent provenienti dal Web
 Wizard.Subscription.search.subtitle3=Quando l'iscrizione sar\u00e0 completa, si riceveranno in tempo reale aggiornamenti nella barra laterale quando saranno disponibili nuovi risultati per la ricerca.
 Wizard.Subscription.rss.subtitle1=Digita o incolla l'URL qui sotto:
-Wizard.Subscription.rss.subtitle2=Molti produttori di contenuti mettono a disposizione un feed RSS. Trova l'URL nel sito del produttore, copia e incolla l'URL nel campo sopra e fai clic su Salva.
+Wizard.Subscription.rss.subtitle2=Molti produttori di contenuti multimediali mettono a disposizione un feed RSS. Trova l'URL nel sito del produttore, copia e incolla l'URL nel campo sopra e fai clic su Salva.
 Wizard.Subscription.rss.subtitle3=Una volta salvato, si riceveranno aggiornamenti in tempo reale nella barra laterale quando saranno disponibili nuovi risultati attraverso il feed RSS.
-Wizard.Subscription.subscribe.library=Contenuto della libreria
+Wizard.Subscription.subscribe.library=Contenuti multimediali nella libreria
 Wizard.Subscription.subscribe.subscriptions=Iscrizioni correlate
 Wizard.Subscription.subscribe.library.empty=Non ci sono iscrizioni disponibili?\n \nCercare i pulsanti arancioni per l'iscrizione nella rete HD di Vuze.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Maggiori informazioni</A>
-TableColumn.header.Info=Informazioni
-TableColumn.header.videoLength=Lunghezza del video
 message.confirm.delete.title=Conferma dell'eliminazione
 message.confirm.delete.text=Eliminare \u00ab%1\u00bb?
 Subscription.menu.properties=Propriet\u00e0
@@ -2662,13 +2584,13 @@ statusbar.feedback.tooltip=Fare clic qui per inviare un commento
 sidebar.Activity=Notifiche
 v3.activity.button.watchall=Segna tutti come visti
 subscriptions.view.help.1=Iscriviti quando vedi
-subscriptions.view.help.2=Ottieni aggiornamenti in tempo reale quando sono disponibili per il download nuovi contenuti. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Maggiori informazioni</A>.
+subscriptions.view.help.2=Ottieni aggiornamenti in tempo reale quando sono disponibili per il download nuovi contenuti multimediali. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Maggiori informazioni</A> (in inglese).
 sidebar.sash.tooltip=Premere F7 per nascondere/visualizzare la barra laterale.
 sidebar.expand.tooltip=Espandi la barra laterale
 sidebar.dropdown.tooltip=Visualizza la barra laterale nel formato menu
-subscript.all.subscribed=Si \u00e8 iscritti a questi contenuti
-subscript.some.subscribed=Si \u00e8 iscritti ad alcune delle iscrizioni disponibili per questo contenuto.\nFare clic per vedere le altre disponibili.
-subscript.none.subscribed=Fare clic per vedere le iscrizioni disponibili per questo contenuto
+subscript.all.subscribed=Si \u00e8 iscritti a questi contenuti multimediali
+subscript.some.subscribed=Si \u00e8 iscritti ad alcune delle iscrizioni disponibili per questo contenuto multimediale.\nFare clic per vedere le altre disponibili.
+subscript.none.subscribed=Fare clic per vedere le iscrizioni disponibili per questo contenuto multimediale
 v3.iconBar.up.tooltip=Sposta su\nTenere premuto il pulsante del mouse per spostare all'inizio.
 v3.iconBar.down.tooltip=Sposta gi\u00f9\nTenere premuto il pulsante del mouse per spostare in fondo.
 TableColumn.header.azsubs.ui.column.subs_link=Associazione
@@ -2678,7 +2600,7 @@ Button.deleteContent.fromComputer=Elimina dal computer
 v3.deleteContent.message=\nSi vuole eliminare \u00ab%1\u00bb dal computer o solo rimuoverlo dalla libreria di Vuze?
 v3.library.infobar.text1=Si sta cercando l'interfaccia avanzata?
 v3.library.infobar.text2=Usare il pulsante per il cambio dell'interfaccia nella barra degli strumenti in alto.
-v3.MainWindow.menu.view.toolbartext=Testo delle barre degli strumenti
+v3.MainWindow.menu.view.toolbartext=Descrizioni nella barra degli strumenti
 v3.MainWindow.menu.view.asSimpleList=Lista semplice
 v3.MainWindow.menu.view.asAdvancedList=Lista avanzata
 v3.MainWindow.menu.view.statusbar=Barra di stato
@@ -2686,13 +2608,15 @@ Subscription.menu.dirtyall=Segna tutti i risultati come non letti
 configureWizard.file.message3=Vuze scaricher\u00e0 i file in una cartella specifica, selezionarla qui:
 v3.deleteContent.applyToAll=Applica l'azione agli %1 elementi selezionati
 ConfigView.label.seeding.firstPriority.ignoreIdleHours=Torrent che non inviano nulla per
-v3.MainWindow.menu.contentnetworks=&Reti in HD
+v3.MainWindow.menu.contentnetworks=&Reti HD
 v3.MainWindow.menu.contentnetworks.about=Informazioni sulle reti HD
 Peers.column.as.info=Dettagli sul sistema autonomo (AS) del peer
 ConfigTransferAutoSpeed.auto.speed.neural=Neurale (Gudy Alpha)
-ConfigView.label.autoopen.downloadbars=Apri automaticamente le barre di download quando
+ConfigView.label.autoopen.downloadbars=Apri automaticamente le barre di download per
 ConfigView.label.autoopen=Apertura automatica
-ConfigView.label.autoopen.detailstab=Apri automaticamente la scheda Dettagli quando
+ConfigView.label.autoopen.detailstab=Apri automaticamente la scheda Dettagli per
+ConfigView.label.autoopen.dl=I download
+ConfigView.label.autoopen.cd=I seed
 ConfigView.label.systray=Vassoio di sistema
 ConfigView.label.systray._mac=Icona della barra di stato
 ConfigView.section.interface.legacy=Vecchio stile
@@ -2703,18 +2627,7 @@ azbuddy.ui.menu.cat.share=Abilita le iscrizioni con l'amico/gli amici
 azbuddy.ui.menu.cat.set=Inserisci le categorie
 azbuddy.ui.menu.cat.set_msg=Lista di categorie separata da spazio, o \u00abAll\u00bb
 azbuddy.ui.menu.cat_subs=Iscriviti
-v3.buddy.prop.dn=Nome visualizzato
-v3.buddy.prop.un=Nome utente
-v3.buddy.prop.on=In linea
-v3.buddy.prop.lupd=Ultimo aggiornamento
-v3.buddy.prop.pks=Conteggio della chiave pubblica
-v3.buddy.prop.pc=Messaggi della chat in attesa
-v3.buddy.prop.catout=Le tue categorie disponibili per i tuoi amici
-v3.buddy.prop.catin=Categorie dell'amico disponibili
-v3.buddy.set.catout=Permetti all'amico di iscriversi alla categoria
-v3.buddy.set.catin=Iscriviti alla categoria dell'amico
 subs.prop.update_period=Periodo di aggiornamento
-azbuddy.enable_cat_pub=Categorie pubbliche a cui TUTTI gli amici possono iscriversi (separate da \u00ab,\u00bb)
 v3.dialog.cnclose.title=%1 chiuso
 v3.dialog.cnclose.subtitle=Notifica
 v3.dialog.cnclose.info1=\u00c8 stata chiusa una rete in HD.
@@ -2726,14 +2639,11 @@ TableColumn.header.#=N\u00b0
 TableColumn.header.#.info=Posizione/Numero d'ordine
 TableColumn.header.category.info=Nome della categoria a cui il torrent appartiene
 TableColumn.header.DateCompleted.info=La data in cui \u00e8 stato completato lo scaricamento del torrent
-TableColumn.header.AzProduct.info=Rete di contenuti origine del torrent
+TableColumn.header.AzProduct.info=Rete di contenuti multimediali da cui \u00e8 stato originato il torrent
 TableColumn.header.health.info=Quanto \u00e8 buona la connessione allo swarm del torrent
-TableColumn.header.Info.info=Pulsante che visualizza la pagina dei dettagli del contenuto Vuze
 TableColumn.header.maxuploads.info=Numero massimo di peer a cui inviare contemporaneamente
 TableColumn.header.name.info=Nome del torrent
 TableColumn.header.unopened.info=Indica se il torrent \u00e8 stato riprodotto (aperto)
-TableColumn.header.Quality.info=Qualit\u00e0 del contenuto Vuze, ad esempio HD o SD
-TableColumn.header.RateIt.info=Per votare il contenuto Vuze
 TableColumn.header.savepath.info=La cartella o il file di destinazione per i dati del torrent
 TableColumn.header.SeedingRank.info=Punteggio che indica quanto il torrent ha bisogno di seed. I valori pi\u00f9 alti indicano un maggiore bisogno.
 TableColumn.header.shareRatio.info=Quanto si \u00e8 inviato (condiviso) in confronto a quanto si \u00e8 scaricato.
@@ -2743,7 +2653,6 @@ TableColumn.header.upspeed.info=Velocit\u00e0 attuale di upload
 TableColumn.header.downspeed.info=Velocit\u00e0 di download attuale
 TableColumn.header.up.info=Quantit\u00e0 di dati inviati ad altri utenti
 TableColumn.header.down.info=Quantit\u00e0 di dati ricevuta dagli altri utenti
-TableColumn.header.videoLength.info=Durata del contenuto video di Vuze
 TableColumn.header.ProgressETA.info=Combina lo stato, il completamento, il tempo rimasto e la velocit\u00e0 di download in una sola colonna, a pi\u00f9 righe
 TableColumn.header.eta.info=Tempo stimato prima del termine del download
 Pieces.column.#=N\u00b0
@@ -2771,13 +2680,14 @@ ColumnSetup.filters=Filtri
 ColumnSetup.availcolumns=Disponibili %1 colonne
 ColumnSetup.availcolumns.filteredby=Sono disponibili %1 colonne, filtrate in base a %2
 devices.view.title=Dispositivi
+device.renderer.view.title=Renderer
 device.mediaserver.view.title=Server per contenuti multimediali
 device.router.view.title=Router
 device.model.desc=Descrizione del modello
 device.model.name=Nome del modello
 device.model.num=Numero del modello
 device.manu.desc=Produttore
-device.router.is_mapping=Mappaggio automatico delle porte
+device.router.is_mapping=Mappatura automatica delle porte
 device.router.req_map=Mappaggi richiesti
 device.router.configure=Configura UPnP
 device.mediaserver.configure=Configurazione del server multimediale
@@ -2818,7 +2728,7 @@ devices.copy.pending=Copia dei file in attesa
 devices.sidebar.hide.rend.generic=Nascondi i dispositivi generici
 v3.devicesview.infobar.text2=Per convertire file per un certo dispositivo, trascinarli dalla libreria nel dispositivo. Per vedere le conversioni completate, fare clic sul dispositivo a destra.
 iconBar.transcode=Dispositivo
-iconBar.transcode.tooltip=Rendi disponibili dei contenuti ad un dispositivo
+iconBar.transcode.tooltip=Rendi disponibili dei contenuti multimediali ad un dispositivo
 device.retry.copy=Riprova a copiare
 devices.copy.fail=Impossibile copiare nel dispositivo
 devices.on.demand=Su richiesta
@@ -2862,8 +2772,8 @@ devices.turnon.title=Attiva il supporto al dispositivo
 devices.choose.device.title=Selezionare un dispositivo di riproduzione per questo video:
 devices.choose.profile.info.text=Dopo la selezione, Vuze rilever\u00e0 automaticamente se il formato video \u00e8 compatibile con il dispositivo, e ne creer\u00e0 una copia compatibile se necessario.\n\nTenere il puntatore del mouse sul dispositivo scelto per maggiori informazioni.
 devices.choose.profile.info.title.selected=Dettagli di %1:
-devices.view.heading=Conversione dei contenuti per la riproduzione sul dispositivo in corso
-device.view.heading=Contenuti per %1
+devices.view.heading=Contenuti multimediali da convertire per un dispositivo
+device.view.heading=Contenuti multimediali per %1
 devices.choose.device.info.title=Suggerimento per i dispositivi
 devices.choose.device.info.text=La prossima volta, trascina semplicemente i file scelti sul dispositivo desiderato nella barra laterale.
 label.clickone=Fai clic su uno
@@ -2890,3 +2800,192 @@ Button.reload=Ricarica
 devices.auto.start=Avvia automaticamente
 Subscription.menu.setcookies=Imposta i cookie
 general.enter.cookies=Cookie dell'elemento
+device.config.xcode.workdir=Cartella di lavoro predefinita per i file convertiti
+MyTorrentsView.menu.clear_alloc_data=Elimina i dati dell'allocazione
+DiskManager.error.nospace=Spazio su disco insufficiente
+DiskManager.error.nospace_fat32={DiskManager.error.nospace} - vedere {wiki.fat32} (in inglese) per maggiori informazioni.
+ConfigView.section.file.rename.incomplete=Aggiungi suffisso ai file incompleti
+subscriptions.config.auto=Scarica automaticamente
+subscriptions.config.autostartdls=Avvia automaticamente i download quando vengono aggiunti (al posto di metterli nello stato Fermato)
+subscriptions.config.autostart.min=Avvia solo se >= MB [0: illimitato]
+subscriptions.config.autostart.max=Avvia solo se <= MB [0: illimitato]
+dlg.corewait.title=Inizializzo il motore principale
+dlg.corewait.text=Attendere...\n\nLa richiesta verr\u00e0 processata dopo l'inizializzazione di Vuze.
+library.core.wait=Attendere...\nInizializzazione del client Vuze in corso
+ConfigView.label.StartUIBeforeCore=Apri l'interfaccia prima dell'inizializzazione
+general.add.friends=Aggiungi i tuoi amici!
+general.all.friends=Tutti gli amici
+friend.mod.subs=Fare clic con il pulsante destro del mouse per modificare le iscrizioni
+TableColumn.header.class=Classe
+device.rss.group=Feed RSS locale
+devices.xcode.rsspub=Pubblica feed RSS
+device.rss.enable=Crea un feed RSS dai contenuti multimediali convertiti - li rende disponibili ai lettori di feed RSS
+device.rss.port=Porta del feed RSS
+device.rss.view=Fare clic per vedere il feed RSS
+device.rss.localonly=Limita l'accesso solo a questo computer
+rcm.rc_tracker.tt=Fare clic aprire il tracker nel browser
+rcm.rc_hash.tt=Fare clic per scaricare questo contenuto multimediale
+rcm.rc_title.tt=Fare clic per cercare questo contenuto multimediale
+devices.xcode.autoCopy=Copia automaticamente nella cartella
+devices.xcode.setcopyto=Imposta la cartella in cui copiare...
+devices.xcode.setcopyto.title=Imposta la posizione in cui copiare
+devices.copy.folder.auto=Copia automaticamente i file nella cartella
+devices.copy.folder.dest=Copia nella cartella
+TableColumn.menu.maxuploads=N\u00b0 Max di upload
+devices.xcode.mancopy=Copia i file manualmente
+devices.xcode.show.cat=Separa in base alla categoria
+ConfigView.label.alwaysShowLibraryHeader=Visualizza sempre l'intestazione nella libreria (I miei torrent)
+devices.cat.show=Visualizza categorie
+devices.tivo.machine=Nome della macchina TiVo
+devices.info.copypending=%1 file sono in attesa di essere copiati.
+device.error.xcodefail=Conversione non riuscita
+device.error.copyfail=La copia di uno o pi\u00f9 file nella cartella non \u00e8 riuscita.
+device.error.copytonotset=\u00abCopia nella cartella\u00bb Non impostato
+device.error.copytomissing=\u00abCopia nella cartella\u00bb \u00ab%1\u00bb Non trovata
+device.error.copytonowrite=\u00abCopia nella cartella\u00bb \u00ab%1\u00bb Non \u00e8 possibile scrivere nella cartella
+device.error.copyfail2=La copia di uno o pi\u00f9 file nel dispositivo non \u00e8 riuscita.
+v3.deviceview.infobar.line2.tivo=Per fare lo stream di video basta selezionare Vuze nella lista In riproduzione del TiVo.
+v3.deviceview.infobar.line2.psp=I video verranno copiati nella PSP quando verr\u00e0 connessa.
+devices.info.copypending2=%1 file sono in attesa di essere copiati, connettere il dispositivo.
+subscriptions.column.nb-subscribers=Sottoscrittori
+device.offlinedownloader.view.title=Scaricamento non il linea
+device.od.enable=Abilita i dispositivi per lo scaricamento non in linea
+device.odauto.enable=Gestisci automaticamente i download
+device.odpt.enable=Includi i torrent privati
+devices.contextmenu.od=Scaricamento non in linea
+devices.contextmenu.od.auto=<Automatico>
+devices.contextmenu.od.enable=Abilita
+devices.contextmenu.od.enabled=Abilitato
+devices.od.view.heading=Download pianificati per lo scaricamento non in linea
+DevicesOD.column.od_completion=Progresso del trasferimento
+devices.od.idle=Pronto
+device.od.turnon.title=Abilita il supporto allo scaricamento non in linea
+device.is.disabled=Il dispositivo \u00e8 disabilitato
+device.configure=Configura...
+device.od.error.notfound=Il dispositivo non \u00e8 connesso
+device.od.error.opfailstatus=Il dispositivo non \u00e8 riuscito a completare il comando %1: stato %2
+device.od.error.opfailexcep=Il dispositivo non \u00e8 riuscito a completare il comando %1: eccezione %2
+device.od.error.nospace=Il dispositivo \u00e8 pieno o non connesso
+device.od.space=Spazio disponibile
+ConfigView.section.style.forceSIValues=Forza la visualizzazione dei valori come IEC, senza considerare l'unit\u00e0 di visualizzazione, per retro-compatibilit\u00e0 (per es. 1MB = 1MiB = 1048576B)
+ConfigView.label.enableSystrayToolTip=Visualizza le statistiche sui download quando ci si sofferma con il mouse sull'icona
+devices.activation=Attivazione dispositivi
+button.nothanks=No, grazie
+devices.od.turnon.text1=Vuze ha rilevato che si \u00e8 connesso un %1.
+devices.od.turnon.text2=Vuoi che il %1 continui a scaricare i file quando il computer non \u00e8 in linea?
+devices.od.turnon.text3=Connettere un hard disk al %1 per abilitare questa funzione.
+devices.od.turnon.learn=Maggiori informazioni >
+devices.od=Programma per il download non in linea
+webui.pairingenable=Abilita l'associazione
+webui.group.access=Controllo dell'accesso
+pairing.accesscode=Codice di accesso
+pairing.ac.getnew=Assegna un nuovo codice di accesso
+pairing.ac.getnew.create=Crea
+pairing.ipv4=Indirizzo IPv4
+pairing.ipv6=Indirizzo IPv6
+pairing.host=Indirizzo dell'host (nome DNS)
+pairing.group.explicit=Dati espliciti
+pairing.explicit.enable=Abilita
+pairing.explicit.info=Normalmente, non \u00e8 necessario specificare esplicitamente i dati IP, perch\u00e9 possono essere determinati automaticamente.\nL'attributo \u00abhost\u00bb pu\u00f2 essere usato, ad esempio, se si \u00e8 registrati a DynDNS e si \u00e8 installato il client per tenere registrato l'IP dinamico.
+pairing.op.fail=Associazione non riuscita
+pairing.alloc.fail=L'assegnazione del nuovo codice di accesso non \u00e8 riuscita.\n%1
+pairing.enable=Abilita l'associazione di Vuze con le interfacce/applicazioni remote
+pairing.status.info=Stato
+pairing.status.registered=Aggiornamento completato (%1)
+pairing.status.pending=L'aggiornamento verr\u00e0 effettuato alle %1
+pairing.status.initialising=Inizializzo
+pairing.status.disabled=Disabilitato
+pairing.view.registered=Fare clic per vedere i dettagli della registrazione attuale
+webui.pairing.info.n=L'associazione \u00e8 disabilitata, vedere le opzioni in Connessione->Associazione per maggiori informazioni su questa funzione.
+webui.pairing.info.y=L'associazione \u00e8 abilitata, vedere le opzioni in Connessione->Associazione per maggiori informazioni.
+subscriptions.rss.enable=Crea feed RSS dalle sottoscrizioni
+# The remaining keys were not in MessagesBundle.properties
+v3.activity.share-content.no-msg=%1 ha condiviso %2 con te
+v3.Share.add.buddy.existing=Amici esistenti:
+v3.buddy.prop.pks=Conteggio della chiave pubblica
+v3.activity.buddy-request.accept=Accetta
+v3.buddies.faq=Maggiori informazioni
+v3.MainWindow.button.sendtofriend=Condividi torrent
+login.optional.message=\u00c8 necessario aver eseguito l'accesso per usare questa funzione
+TableColumn.header.videoLength=Lunghezza del video
+v3.Share.wizard.title=Assistente alla condivisione
+v3.MainWindow.button.newtag.share=Nuovo! Condividi il torrent
+azbuddy.ui.dialog.disable.title=Disabilitazione del plugin Amici
+TableColumn.header.Info.info=Pulsante che visualizza la pagina dei dettagli del contenuto multimediale di Vuze
+v3.activity.share-content=%1 ha condiviso %2 con te. %3 <A HREF="%4" TITLE="%5">dice...</A>
+v3.Share.header.message=Condividi con gli amici attuali, o aggiungi nuovi amici.
+MainWindow.menu.community.add_friends=&Aggiungi amici
+v3.Share.header=Condividi
+message.confirm.invite.error=Ahi! C'\u00e8 stato un errore in questa richiesta. Sono presenti errori in uno o pi\u00f9 inviti.
+v3.activity.header.friend.requests.fromyou=Richieste di amicizia - inviate
+v3.MainWindow.menu.view.buddies-viewer=Barra degli amici
+v3.activity.header.rating.reminders=Promemoria per le votazioni
+message.intro.friends=Aggiungi amici.\nCondividi torrent.\nScarica pi\u00f9 velocemente.
+v3.AddFriends.header.message=Aggiungere amici per condividere i torrent preferiti
+v3.Share.add.edit.buddy=Aggiungi/Modifica gli amici
+v3.buddies.disabled.title=Plugin degli amici disabilitato
+ConfigView.section.security.vuze.login=\u00c8 necessario effettuare l'accesso a Vuze per usare questa funzione
+v3.chat.wrongversion=%1 usa una versione di Vuze che non supporta la chat.
+v3.AddFriends.header=Aggiungi amici
+message.prompt.add.friends=Selezionare degli amici dalla barra laterale (in basso a sinistra)
+v3.Share.send.now=Invia
+v3.Share.add.buddy.all=Condividi con tutti
+v3.Share.buddies=Amici
+v3.AddFriends.wizard.title=Assistente all'aggiunta di amici
+message.confirm.share.singular=Ottimo! La tua richiesta di condivisione di un torrent \u00e8 stata inviata.
+v3.activity.buddy-request=\u00c8 presente una richiesta di amicizia da %1.
+v3.Share.invite.buddies.prompt=Invita altri amici con cui condividere
+TableColumn.header.RateIt.info=Per votare il contenuto multimediale di Vuze
+v3.buddies.remove.buddy.dialog.title=Rimuovi
+v3.buddy.prop.catin=Categorie dell'amico disponibili
+v3.buddies.online=In linea (%1)
+message.confirm.share.invite.singular=Ottimo! La richiesta di connessione e condivisione \u00e8 stata inviata. Puoi dire all'amico di accettarla.
+TableColumn.header.Quality.info=Qualit\u00e0 del contenuto multimediale di Vuze, ad esempio HD o SD
+v3.MainWindow.menu.publish.about=Informazioni sulla pubblicazione...
+v3.Share.add.buddy.new=Nuovi amici:
+v3.buddies.remove=Rimuovi amico
+v3.MainWindow.menu.publish.mine=Contenuti multimediali pubblicati
+v3.Share.add.buddy=Aggiungi amici
+azbuddy.enable_cat_pub=Categorie pubbliche a cui TUTTI gli amici possono iscriversi (separate da \u00ab,\u00bb)
+v3.buddies.dnd.info.dialog.title=Condivisione attraverso il trascinamento
+v3.buddies.dnd.info.dialog.remember=Non visualizzare ancora questo messaggio
+v3.Share.disclaimer.link=Maggiori informazioni
+message.confirm.invite.singular=Ottimo! La richiesta di amicizia \u00e8 stata inviata. Puoi dire all'amico di accettarla.
+v3.buddy.prop.catout=Le tue categorie disponibili per i tuoi amici
+v3.activity.buddy-linkup=Si \u00e8 ora amici di %1.
+v3.activity.header.friend.requests.accepted=Richieste di amicizia - accettate
+v3.buddy.menu.viewprofile=Visualizza profilo
+TableColumn.header.Info=Informazioni
+v3.activity.buddy-invited.multi=La richiesta di amicizia \u00e8 stata inviata a:\n%1
+TableColumn.header.Rating_global.info=La valutazione globale per questo contenuto multimediale
+v3.buddy.prop.un=Nome utente
+v3.buddy.prop.dn=Nome visualizzato
+v3.buddies.dnd.info.dialog.text=\u00c8 stata inziata una condivisione attraverso il trascinamento. Si stanno preparando i contenuti multimediali per la condivisione, e la schermata di condivisione verr\u00e0 aperta quando saranno pronti.\n\n\u00c8 necessario tenere aperto Vuze affinch\u00e9 l'amico riceva i contenuti.\n<A HREF="http://faq.vuze.com/?View=entry&EntryID=267">Ulteriori informazioni</A> (in inglese).
+v3.Share.optional.message=Messaggio opzionale inviato come notifica (massimo 140 caratteri):
+message.confirm.share.invite.plural=Ottimo! Le richieste di connessione e condivisione sono state inviate. Puoi dire ai tuoi amici di accettarle.
+v3.activity.buddy-invited=La richiesta di amicizia \u00e8 stata inviata a %1.
+v3.buddies.disabled.text._mac=Il plugin degli amici \u00e8 stato disabilitato, impedendo di poter condividere o accettare torrent o richieste di amicizia. Si possono cambiare le impostazoni nella finestra Configurazione.
+v3.buddy.set.catin=Iscriviti alla categoria dell'amico
+message.confirm.invite.plural=Ottimo! Le richieste di amicizia sono state inviate. Puoi dire ai tuoi amici di accettarle.
+azbuddy.ui.dialog.disable.text=La disabilitazione del plugin Amici impedir\u00e0 di condividere torrent usando la barra degli amici nella parte bassa della finestra e di modificare la lista degli amici.\n\nDisabilitare gli amici?
+v3.buddy.prop.on=In linea
+v3.buddy.prop.pc=Messaggi della chat in attesa
+v3.Share.invitees=Invitati
+v3.buddies.remove.buddy.dialog.text=Rimuovere l'amico %1?
+v3.activity.header.share.requests=Richieste di condivisione di torrent
+TableColumn.header.videoLength.info=Durata del contenuto video di Vuze
+v3.Share.menu=Condividi contenuti multimediali
+v3.buddies.disabled.text._windows=Il plugin degli amici \u00e8 stato disabilitato, impedendo di poter condividere o accettare torrent o richieste di amicizia. Si possono cambiare le impostazoni nella finestra Opzioni.
+v3.buddy.set.catout=Permetti all'amico di iscriversi alla categoria
+v3.MainWindow.menu.publish.new=Pubblica contenuti multimediali
+v3.activity.header.friend.requests.foryou=Richieste di amicizia - ricevute
+v3.buddy.prop.lupd=Ultimo aggiornamento
+v3.buddy.menu.remove=Rimuovi amico
+v3.chat.offline=%1 non \u00e8 in linea, ricever\u00e0 il messaggio quando torner\u00e0 disponibile.
+message.confirm.share.plural=Ottimo! Le tue richieste di condivisione di un torrent sono state inviate.
+v3.buddies.add.to.share=Aggiungi amico alla condivisione
+TableColumn.header.Rating_global=Valutazione
+v3.activity.buddy-request.multi=\u00c8 presente una richiesta di amicizia (n\u00b0%3) da %1.
+v3.MainWindow.button.share=Condividi contenuti multimediali
+v3.buddies.friends=Amici
+v3.Share.disclaimer=Nota: sia il contenuto multimediale condiviso sia questo messaggio opzionale saranno criptati.
diff --git a/org/gudy/azureus2/internat/MessagesBundle_ja_JP.properties b/org/gudy/azureus2/internat/MessagesBundle_ja_JP.properties
index 7696293..c8cb0df 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_ja_JP.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_ja_JP.properties
@@ -154,7 +154,7 @@ ConfigView.label.autoupdate=\u65b0\u3057\u3044\u30d0\u30fc\u30b8\u30e7\u30f3\u30
 ConfigView.label.openconsole=\u8d77\u52d5\u6642\u306b\u30b3\u30f3\u30bd\u30fc\u30eb\u3092\u958b\u304f
 ConfigView.label.openconfig=\u8d77\u52d5\u6642\u306b\u74b0\u5883\u8a2d\u5b9a\u3092\u958b\u304f
 ConfigView.label.startminimized=\u8d77\u52d5\u5f8c\u306b\u6700\u5c0f\u5316
-ConfigView.label.ircwiki=http://azureus.aelitis.com/wiki/index.php/Rules_for_IRC \u3092\u3054\u89a7\u304f\u3060\u3055\u3044
+ConfigView.label.ircwiki=http://wiki.vuze.com/index.php/Rules_for_IRC \u3092\u3054\u89a7\u304f\u3060\u3055\u3044
 ConfigView.label.ircserver=\u30b5\u30fc\u30d0\uff1a
 ConfigView.label.ircchannel=\u30c1\u30e3\u30cd\u30eb\uff1a
 ConfigView.label.irclogin=\u30cb\u30c3\u30af\u30cd\u30fc\u30e0\uff1a
@@ -1276,7 +1276,7 @@ wizard.maketorrents.autoopen=\u4f5c\u6210\u5f8c\u3001\u30b7\u30fc\u30c9\u30e2\u3
 ConfigView.section.sharing.rescanenable=\u5b9a\u671f\u7684\u306b\u5171\u6709\u304c\u5909\u66f4\u3055\u308c\u3066\u3044\u306a\u3044\u304b\u518d\u30b9\u30ad\u30e3\u30f3
 ConfigView.section.sharing.rescanperiod=\u518d\u30b9\u30ad\u30e3\u30f3\u9593\u9694\uff08\u79d2\uff09
 ConfigView.section.connection.advanced=\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u8a73\u7d30
-ConfigView.section.connection.advanced.url=http://azureus.aelitis.com/wiki/index.php/AdvancedNetworkSettings
+ConfigView.section.connection.advanced.url=http://wiki.vuze.com/index.php/AdvancedNetworkSettings
 ConfigView.section.connection.advanced.mtu=MTU
 ConfigView.section.connection.advanced.mtu.tooltip=Maximum size of a packet that can be transferred in one frame over a network.\nVuze uses MTU-40 (MSS) for upload packet-payload optimizations.\nRecommended values:\n  576 - Dial-up connections\n1492 - PPPoE broadband connections\n1500 - Ethernet, DSL and Cable broadband connections 
 ConfigView.section.connection.advanced.SO_RCVBUF=SO_RCVBUF \u30b5\u30a4\u30ba [0: OS \u306e\u30c7\u30d5\u30a9\u30eb\u30c8\u5024]
@@ -1894,7 +1894,7 @@ UIDebugGenerator.complete.title=\u30c7\u30d0\u30c3\u30b0\u60c5\u5831\u306e\u751f
 UIDebugGenerator.complete.text=\u30d5\u30a1\u30a4\u30eb '%1' \u3092 az-bugreports at azureus-inc.com \u3078\u9001\u3063\u3066\u304f\u3060\u3055\u3044\u3002\n\nOK \u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u3068\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304d\u307e\u3059\u3002
 ConfigView.section.style.showProgramIcon='\u540d\u524d'\u5217\u306b\u30d7\u30ed\u30b0\u30e9\u30e0\u30a2\u30a4\u30b3\u30f3\u3092\u8868\u793a
 ConfigView.section.style.showProgramIcon.tooltip=\u5909\u66f4\u5185\u5bb9\u306f\u6b21\u306b\u958b\u3044\u305f\u3068\u304d\u306b\u6709\u52b9\u306b\u306a\u308a\u307e\u3059
-swt.alert.cant.update=%3" \u304b\u3089\u30ed\u30fc\u30c9\u3055\u308c\u305f SWT \u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30d0\u30fc\u30b8\u30e7\u30f3 %1 \u304b\u3089 %2 \u3078\u81ea\u52d5\u7684\u306b\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\uff08"%4" \u304b\u3089\u30ed\u30fc\u30c9\u3055\u308c\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\uff09\u3002\u8a73\u3057\u304f\u306f <A HREF="http://azureus.aelitis.com/wiki/index.php/SWT_Cant_Auto_Update">the wiki</A> \u3092\u3054\u89a7\u304f\u3060\u3055\u3044\u3002
+swt.alert.cant.update=%3" \u304b\u3089\u30ed\u30fc\u30c9\u3055\u308c\u305f SWT \u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30d0\u30fc\u30b8\u30e7\u30f3 %1 \u304b\u3089 %2 \u3078\u81ea\u52d5\u7684\u306b\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\uff08"%4" \u304b\u3089\u30ed\u30fc\u30c9\u3055\u308c\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\uff09\u3002\u8a73\u3057\u304f\u306f <A HREF="http://wiki.vuze.com/index.php/SWT_Cant_Auto_Update">the wiki</A> \u3092\u3054\u89a7\u304f\u3060\u3055\u3044\u3002
 authenticator.savepassword=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u4fdd\u5b58
 ConfigView.section.security.clearpasswords=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u30ea\u30bb\u30c3\u30c8
 ConfigView.section.security.clearpasswords.button=\u30ea\u30bb\u30c3\u30c8
diff --git a/org/gudy/azureus2/internat/MessagesBundle_li_NL.properties b/org/gudy/azureus2/internat/MessagesBundle_li_NL.properties
index abeef2d..1c86bd0 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_li_NL.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_li_NL.properties
@@ -148,7 +148,7 @@ ConfigView.label.openconsole=Console \u00e4\u00f6pene tiedes 't sjtarte
 ConfigView.label.openconfig=K\u00f3ngfiggerasie \u00e4\u00f6pene tiedes 't sjtarte
 ConfigView.label.startminimized=Start geminimaliseerd 
 ConfigView.section.irc=Irc 
-ConfigView.label.ircwiki=Laes estebleef http://azureus.aelitis.com/wiki/index.php/Rules_for_IRC
+ConfigView.label.ircwiki=Laes estebleef http://wiki.vuze.com/index.php/Rules_for_IRC
 ConfigView.label.ircserver=Server 
 ConfigView.label.ircchannel=Kanaal 
 ConfigView.label.irclogin=Sjirmnaam
@@ -2480,7 +2480,7 @@ Progress.reporting.prompt.label.remove.tooltip=Verwijder dit Voortgang Raport ui
 v3.mb.UnknownContent.button.cancel=Annuleer
 ConfigView.label.bindip.info=Es veurbild, '192.168.1.2' of 'eth0' (huidige: %1)
 Progress.reporting.prompt.label.detail.tooltip=Toon deze voortgang Raportage in het detail scherm
-ConfigView.section.connection.advanced.IPTOS=Uitgaande packet type-of-service (TOS) [zie http://azureus.aelitis.com/wiki/index.php/AdvancedNetworkSettings]
+ConfigView.section.connection.advanced.IPTOS=Uitgaande packet type-of-service (TOS) [zie http://wiki.vuze.com/index.php/AdvancedNetworkSettings]
 network.ltep.enabled=Gebruik maken van het experimentelen extensie protocol handshake ondersteuning  (herstart vereist)
 xmlhttp.config.option.debug.serialisation=Output XML handeling/behandeling
 v3.mb.notTrusted.button.run=Weg gaan
diff --git a/org/gudy/azureus2/internat/MessagesBundle_ro_RO.properties b/org/gudy/azureus2/internat/MessagesBundle_ro_RO.properties
index 88d517d..799e7c5 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_ro_RO.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_ro_RO.properties
@@ -155,7 +155,7 @@ ConfigView.label.autoupdate=Deschide dialogul de Promovare [Upgrade] c\u00eend e
 ConfigView.label.openconsole=Deschide Consola la pornire
 ConfigView.label.openconfig=Deschide Op\u021biunile la pornire
 ConfigView.label.startminimized=Porne\u0219te minimizat
-ConfigView.label.ircwiki=Citi\u021bi http://azureus.aelitis.com/wiki/index.php/Rules_for_IRC
+ConfigView.label.ircwiki=Citi\u021bi http://wiki.vuze.com/index.php/Rules_for_IRC
 ConfigView.label.ircchannel=Canal
 ConfigView.label.irclogin=Porecl\u0103
 ConfigView.group.irctitle=Set\u0103ri IRC
@@ -631,6 +631,7 @@ TableColumn.header.completion.info=Reprezentare grafic\u0103 a % desc\u0103rcat
 ConfigView.section.style.showdownloadbasket=Arat\u0103 Co\u0219ul de Desc\u0103rcare (pt. tras \u0219i depus torente)
 ConfigView.section.style.alwaysShowTorrentFiles=Arat\u0103 mereu fi\u0219ierele torent \u00een Detalii/Fi\u0219iere
 wizard.multitracker=Adaug\u0103 la torent informa\u021bia despre Multi-Tracker
+wizard.multitracker.title=Tracker Multiplu
 wizard.multitracker.configuration=Configura\u021bia Multi-Trackerului
 wizard.multitracker.new=Nou...
 wizard.multitracker.edit=Editeaz\u0103..
@@ -1900,11 +1901,11 @@ MyTorrentsView.menu.rename.displayed=Modific\u0103 Numele Afi\u0219at
 MyTorrentsView.menu.rename.save_path=Redenume\u0219te Calea de Salvare
 MyTorrentsView.menu.rename.displayed_and_save_path=Redenume\u0219te Ambele
 MyTorrentsView.menu.rename.displayed.enter.title=Modific\u0103 Numele Afi\u0219at
-MyTorrentsView.menu.rename.displayed.enter.message=Introduce\u021bi un nume nou ce va fi afi\u0219at pentru aceast\u0103 desc\u0103rcare.\nDac\u0103 nu e introdus nici un text, va fi utilizat numele original.
+MyTorrentsView.menu.rename.displayed.enter.message=Introduce\u021bi un nume nou ce va fi afi\u0219at pentru aceast\u0103 desc\u0103rcare.
 MyTorrentsView.menu.rename.save_path.enter.title=Redenume\u0219te Calea de Salvare
-MyTorrentsView.menu.rename.save_path.enter.message=Introduce\u021bi o cale nou\u0103 de salvare pentru aceast\u0103 desc\u0103rcare.\nDac\u0103 nu e introdus nici un text, va fi utilizat numele afi\u0219at al desc\u0103rc\u0103rii.
+MyTorrentsView.menu.rename.save_path.enter.message=Introduce\u021bi o cale nou\u0103 de salvare pentru aceast\u0103 desc\u0103rcare.
 MyTorrentsView.menu.rename.displayed_and_save_path.enter.title=Redenume\u0219te Desc\u0103rcarea
-MyTorrentsView.menu.rename.displayed_and_save_path.enter.message=Introduce\u021bi un nume nou pentru aceast\u0103 desc\u0103rcare.\nDac\u0103 nu e introdus nici un text, vor fi utilizate valorile originale.
+MyTorrentsView.menu.rename.displayed_and_save_path.enter.message=Introduce\u021bi un nume nou pentru aceast\u0103 desc\u0103rcare.
 MyTorrentsView.menu.edit_comment=Editeaz\u0103 Comentariul
 MyTorrentsView.menu.edit_comment.enter.title=Editeaz\u0103 Comentariul
 MyTorrentsView.menu.edit_comment.enter.message=Ad\u0103uga\u021bi un comentariu pt. aceast\u0103 desc\u0103rcare.
@@ -2928,6 +2929,7 @@ general.enter.cookies=Fursecurile intr\u0103rii [cookies]
 device.config.xcode.workdir=Dosarul implicit de lucru pentru fi\u0219ierele transcodate
 MyTorrentsView.menu.clear_alloc_data=Cur\u0103\u021b\u0103 Starea de Alocare
 DiskManager.error.nospace=Spa\u021biu de stocare insuficient
+DiskManager.error.nospace_fat32={DiskManager.error.nospace} - citi\u021bi {wiki.fat32}
 ConfigView.section.file.rename.incomplete=Adaug\u0103 sufix la fi\u0219ierele incomplete
 subscriptions.config.auto=Autodescarc\u0103
 subscriptions.config.autostartdls=Porne\u0219te automat desc\u0103rc\u0103rile la ad\u0103ugarea lor (\u00een contrast cu punerea \u00een stare oprit\u0103)
@@ -2936,6 +2938,41 @@ subscriptions.config.autostart.max=Porne\u0219te doar dac\u0103 <= MB [0: nelimi
 dlg.corewait.title=Ini\u021bializez Nucleul
 dlg.corewait.text=A\u0219tepta\u021bi un moment...\n\nSolicitarea va fi procesat\u0103 dup\u0103 ce se va termina ini\u021bializarea Vuze
 library.core.wait=A\u0219tepta\u021bi un pic...\nClientul Vuze este ini\u021bializat
+ConfigView.label.StartUIBeforeCore=Porne\u0219te interfa\u021ba grafic\u0103 \u00eenaintea ini\u021bializ\u0103rii nucleului softului
+general.add.friends=Ad\u0103uga\u021bi ni\u0219te prieteni!
+general.all.friends=To\u021bi Prietenii
+friend.mod.subs=Clica\u021bi-dreapta pentru a modifica abonamentele
+TableColumn.header.class=Clas\u0103
+device.rss.group=Flux RSS Local
+devices.xcode.rsspub=Public\u0103 Fluxul RSS
+device.rss.enable=Creeaz\u0103 un flux RSS din con\u021binutul transcodat - aceasta pune la dispozi\u021bie con\u021binutul pentru cititoarele RSS
+device.rss.port=Portul Fluxului RSS
+device.rss.view=Clica\u021bi pentru a vedea fluxul RSS
+device.rss.localonly=Restric\u021bioneaz\u0103 accesul, fiind permis doar de la acest calculator
+rcm.rc_tracker.tt=Clica\u021bi pentru a explora trackerul
+rcm.rc_hash.tt=Clica\u021bi pentru a desc\u0103rca acest con\u021binut
+rcm.rc_title.tt=Clica\u021bi pentru a c\u0103uta acest con\u021binut
+devices.xcode.autoCopy=Copiaz\u0103 Automat \u00een Dosar
+devices.xcode.setcopyto=Seteaz\u0103 Dosarul de Copiere...
+devices.xcode.setcopyto.title=Alege locul unde s\u0103 se copieze
+devices.copy.folder.auto=Copiaz\u0103 automat fi\u0219ierele \u00een dosar
+devices.copy.folder.dest=Copiaz\u0103 \u00een Dosar
+devices.xcode.mancopy=Copiaz\u0103 Manual Fi\u0219ierele
+devices.xcode.show.cat=Separat dup\u0103 Categorie
+ConfigView.label.alwaysShowLibraryHeader=Arat\u0103 mereu antetul \u00een Arhiva Torentelor (Torentele Mele)
+devices.cat.show=Arat\u0103 categoriile
+devices.tivo.machine=Numele aparatului TiVo
+devices.info.copypending=%1 fi\u0219iere a\u0219teapt\u0103 s\u0103 fie copiate
+device.error.xcodefail=Transcodarea a e\u0219uat
+device.error.copyfail=Unul sau mai multe fi\u0219iere nu au putut fi copiate \u00een dosar
+device.error.copytonotset='Copiaz\u0103 \u00een Dosar' nu a fost setat
+device.error.copytomissing='Copiaz\u0103 \u00een Dosar' "%1" nu a fost g\u0103sit
+device.error.copytonowrite='Copiaz\u0103 \u00een Dosar' "%1" nu permite scrierea
+device.error.copyfail2=Unul sau mai multe fi\u0219iere nu au putut fi copiate pe dispozitiv
+v3.deviceview.infobar.line2.tivo=Fluxa\u021bi [stream] videouri select\u00eend Vuze \u00een Lista de Redare Curent\u0103 [Now Playing List] de la aparatul TiVo.
+v3.deviceview.infobar.line2.psp=Videourile vor fi copiate pe PSP c\u00eend va fi conectat.
+devices.info.copypending2=%1 File(s) fi\u0219iere a\u0219teapt\u0103 s\u0103 fie copiate, conecta\u021bi dispozitivul
+subscriptions.column.nb-subscribers=Abona\u021bi
 # The remaining keys were not in MessagesBundle.properties
 MyTorrentsView.availability.info=Nr. copii complete descoperite
 MyTorrentsView.upspeed=\u00cenc\u0103rcare
@@ -2952,6 +2989,7 @@ MyTorrentsView.done.info=Procentajul realizat din sarcina curent\u0103
 MyTorrentsView.SeedingRank=Rang de Donare
 MyTorrentsView.OnlyCDing4.info=Timpul c\u00eet torentul a fost exclusiv donat. Se exclude timpul c\u00eet torentul a fost at\u00eet desc\u0103rcat c\u00eet \u0219i donat.
 Wizard.Subscription.optin.help=Activeaz\u0103 Abonamentele :
+MyTorrentsView.menu.rename.displayed_and_save_path.enter.message.2=Dac\u0103 nu e introdus nici un text, vor fi utilizate valorile originale.
 v3.MainWindow.recentDL=Ultimele %1 Desc\u0103rc\u0103ri
 MyTorrentsView.swarm_average_speed=Viteza Medie a Roiului
 MyTorrentsView.tracker=Tracker
@@ -2972,8 +3010,10 @@ MyTorrentsView.category=Categorie
 MyTorrentsView.completed.info=nr. de parteneri care au terminat de desc\u0103rcat torentul, a\u0219a cum e raportat de tracker
 MyTorrentsView.timesinceupload=\u00cenc\u0103rcare Inactiv\u0103 de
 MyTorrentsView.shareRatio=Raport de Partajare
+MyTorrentsView.menu.rename.save_path.enter.message.2=Dac\u0103 nu e introdus nici un text, va fi utilizat numele afi\u0219at al desc\u0103rc\u0103rii.
 MyTorrentsView.seed_to_peer_ratio=Raport Donatori/Parteneri
 MyTorrentsView.comment=Comentariu
+MyTorrentsView.menu.rename.displayed.enter.message.2=Dac\u0103 nu e introdus nici un text, va fi utilizat numele original.
 MyTorrentsView.trackernextaccess.info=C\u00eend are loc din nou accesarea trackerului
 MyTorrentsView.health=S\u0103n\u0103tate
 MyTorrentsView.AvgAvail.info=Suma p\u0103r\u021bilor disponibile divizat\u0103 prin nr. de p\u0103r\u021bi, divizat\u0103 prin nr. de conexiuni
diff --git a/org/gudy/azureus2/internat/MessagesBundle_uk_UA.properties b/org/gudy/azureus2/internat/MessagesBundle_uk_UA.properties
index ec7ef27..6d6612d 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_uk_UA.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_uk_UA.properties
@@ -1,6 +1,6 @@
 #There is a plugin to help with internationalizing these bundles at http://azureus.sourceforge.net/plugin_list.php
 MainWindow.menu.file.open.torrent=\u0422\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b...
-Main.parameter.usage=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f : java org.gudy.azureus2.cl.Main [\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438] "\u0444\u0430\u0439\u043b.torrent" "\u043c\u0456\u0441\u0446\u0435 \u0437\u0430\u043f\u0438\u0441\u0443"
+Main.parameter.usage=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f : java org.gudy.azureus2.cl.Main [\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438] "\u0444\u0430\u0439\u043b.torrent" "\u0440\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f"
 Main.parameter.maxUploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043e\u0434\u043d\u043e\u0447\u0430\u0441\u043d\u0438\u0445 \u0440\u043e\u0437\u0434\u0430\u0447
 Main.parameter.maxSpeed=\u041c\u0430\u043a\u0441. \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u0411\u0430\u0439\u0442/\u0441
 MainWindow.menu.file=&\u0424\u0430\u0439\u043b
@@ -12,7 +12,7 @@ MainWindow.menu.file.export=&\u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u0442\u
 MainWindow.menu.file.import=&\u0406\u043c\u043f\u043e\u0440\u0442 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 MainWindow.menu.file.closetab=&\u0417\u0430\u043a\u0440\u0438\u0442\u0438 \u0432\u043a\u043b\u0430\u0434\u043a\u0443
 MainWindow.menu.file.closewindow=\u0417\u0430\u043a\u0440\u0438\u0442\u0438 &\u0432\u0456\u043a\u043d\u043e
-MainWindow.menu.file.exit=\u0417\u0430\u043a&\u0440\u0438\u0442\u0438
+MainWindow.menu.file.exit=\u0412\u0438&\u0445\u0456\u0434
 MainWindow.dialog.choose.file=\u0412\u0438\u0431\u0456\u0440 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 MainWindow.menu.file.folder=\u0422\u0435&\u043a\u0430
 MainWindow.dialog.choose.folder=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0442\u0435\u043a\u0443 \u0437 \u0442\u043e\u0440\u0435\u043d\u0442\u0430\u043c\u0438
@@ -21,17 +21,17 @@ MainWindow.menu.view.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438
 MainWindow.menu.view.mytorrents=&\u041c\u043e\u0457 \u0442\u043e\u0440\u0435\u043d\u0442\u0438
 MainWindow.menu.view.open_global_transfer_bar=\u041f\u0430\u043d\u0435\u043b\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447
 MainWindow.menu.view.configuration=&\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f...
-MainWindow.menu.view.console=\u041a\u043e\u043d&\u0441\u043e\u043b\u044c
+MainWindow.menu.view.console=&\u041a\u043e\u043d\u0441\u043e\u043b\u044c
 MainWindow.menu.view.allpeers=\u0412\u0441\u0456 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0438
-MainWindow.menu.view.detailedlist=&\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a
+MainWindow.menu.view.detailedlist=&\u0414\u043e\u043a\u043b\u0430\u0434\u043d\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a
 MainWindow.menu.closealldetails=\u0417\u0430\u043a\u0440\u0438\u0442\u0438 \u0432\u0441\u0456 &\u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456
 MainWindow.menu.closealldownloadbars=\u0417\u0430\u043a\u0440\u0438\u0442\u0438 \u0432\u0441\u0456 &\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 MainWindow.menu.language=&\u041c\u043e\u0432\u0430
 ConfigView.section.language=\u041c\u043e\u0432\u0430
-MainWindow.menu.window=&\u0412\u0456\u043a\u043d\u043e
+MainWindow.menu.window=\u0412\u0456\u043a&\u043d\u043e
 MainWindow.menu.window.minimize=&\u0417\u0433\u043e\u0440\u043d\u0443\u0442\u0438
 MainWindow.menu.window.zoom=&\u0417\u0431\u0456\u043b\u044c\u0448\u0438\u0442\u0438
-MainWindow.menu.window.alltofront=\u0417\u0432\u0435\u0440\u0445\u0443 \u0432\u0441\u0456\u0445
+MainWindow.menu.window.alltofront=\u0417\u0433\u043e\u0440\u0438 \u0432\u0441\u0456\u0445
 MainWindow.menu.help=&\u0414\u043e\u0432\u0456\u0434\u043a\u0430
 MainWindow.menu.help.about=\u041f\u0440\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0443 Vuze
 MainWindow.menu.torrent=T&\u043e\u0440\u0435\u043d\u0442
@@ -42,12 +42,12 @@ MainWindow.about.section.system=\u0421\u0438\u0441\u0442\u0435\u043c\u0430
 MainWindow.about.section.internet=\u0406\u043d\u0442\u0435\u0440\u043d\u0435\u0442
 MainWindow.about.internet.homepage=\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0430 Vuze
 MainWindow.about.internet.sourceforge=\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u043d\u0430 Sourceforge
-MainWindow.about.internet.sourceforgedownloads=\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0430 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u0437 Sourceforge
+MainWindow.about.internet.sourceforgedownloads=\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0430 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437 Sourceforge
 MainWindow.about.internet.bugreports=\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u0438\u0442\u0438 \u043f\u0440\u043e \u043f\u043e\u043c\u0438\u043b\u043a\u0443
-MainWindow.about.internet.forumdiscussion=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0438\u0439 \u0444\u043e\u0440\u0443\u043c
+MainWindow.about.internet.forumdiscussion=\u0424\u043e\u0440\u0443\u043c\u0438
 MainWindow.about.internet.wiki=Wiki-\u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0430 \u0437 FAQ \u043f\u0440\u043e Vuze
-MainWindow.dialog.choose.savepath=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043f\u0430\u043f\u043a\u0443 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
-MainWindow.dialog.choose.savepath_forallfiles=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0443 \u043f\u0430\u043f\u043a\u0443 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
+MainWindow.dialog.choose.savepath=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0442\u0435\u043a\u0443 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
+MainWindow.dialog.choose.savepath_forallfiles=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0443 \u0442\u0435\u043a\u0443 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
 MainWindow.status.latestversion=\u041e\u0441\u0442\u0430\u043d\u043d\u044f \u0432\u0435\u0440\u0441\u0456\u044f
 MainWindow.status.latestversion.clickupdate=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438
 MainWindow.status.unknown=\u043d\u0435\u0432\u0456\u0434\u043e\u043c\u043e
@@ -75,7 +75,7 @@ TableColumn.header.trackernextaccess.info=\u041d\u0430\u0441\u0442\u0443\u043f\u
 TableColumn.header.priority=\u041f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442
 TableColumn.header.priority.info=\u0412\u0438\u0437\u043d\u0430\u0447\u0430\u0454 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0430
 TableColumn.header.seeds.fullcopycalc=%2 \u043f\u043e\u0432\u043d\u0438\u0445 \u043a\u043e\u043f\u0456\u0439 \u043f\u0435\u0440\u0435\u0431\u0443\u0432\u0430\u044e\u0442\u044c \u0432 %1 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432
-MyTorrentsView.menu.showdetails=&\u0412\u043b\u0430\u0441\u0442\u0438\u0432\u043e\u0441\u0442\u0456
+MyTorrentsView.menu.showdetails=\u041f\u043e&\u0434\u0440\u043e\u0431\u0438\u0446\u0456
 MyTorrentsView.menu.showdownloadbar=\u041f\u0430\u043d\u0435\u043b\u044c &\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 MyTorrentsView.menu.open=&\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438
 MyTorrentsView.menu.setpriority=\u0417\u0430\u0434\u0430\u0442\u0438 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442
@@ -84,67 +84,68 @@ MyTorrentsView.menu.setpriority.low=&\u041d\u0438\u0437\u044c\u043a\u0438\u0439
 MyTorrentsView.menu.start=&\u041f\u043e\u0447\u0430\u0442\u0438
 MyTorrentsView.menu.stop=&\u0417\u0443\u043f\u0438\u043d\u0438\u0442\u0438
 MyTorrentsView.menu.remove=\u0412\u0438&\u043b\u0443\u0447\u0438\u0442\u0438
-MyTorrentsView.menu.changeTracker=&\u0414\u043e\u0434\u0430\u0442\u0438 URL \u0442\u0440\u0435\u043a\u0435\u0440\u0443
+MyTorrentsView.menu.changeTracker=&\u0414\u043e\u0434\u0430\u0442\u0438 \u0430\u0434\u0440\u0435\u0441\u0443 \u0442\u0440\u0435\u043a\u0435\u0440\u0443
 TrayWindow.menu.exit=&\u0412\u0438\u0439\u0442\u0438
 TrayWindow.menu.show=\u041f\u043e&\u043a\u0430\u0437\u0430\u0442\u0438 Vuze
 SystemTray.menu.exit=\u0412\u0438\u0439\u0442\u0438
 SystemTray.menu.closealldownloadbars=\u0417\u0430\u043a\u0440\u0438\u0442\u0438 \u0432\u0441\u0456 \u043f\u0430\u043d\u0435\u043b\u0456
 SystemTray.menu.open_global_transfer_bar=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447
 SystemTray.menu.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 Vuze
-PeersView.ip.info=IP \u0442\u043e\u0433\u043e, \u0445\u0442\u043e \u0440\u043e\u0437\u0434\u0430\u0454
+PeersView.ip=IP-\u0430\u0434\u0440\u0435\u0441\u0430
+PeersView.ip.info=IP \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
 PeersView.port=\u041f\u043e\u0440\u0442
 PeersView.port.info=\u041f\u043e\u0440\u0442, \u044f\u043a\u0438\u0439 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f 
-PeersView.T.info=l (local): \u0412\u0438 \u0437'\u0454\u0434\u043d\u0430\u043b\u0438\u0441\u044f, r (remote): \u0443\u0447\u0430\u0441\u043d\u0438\u043a \u0437'\u0454\u0434\u043d\u0430\u0432\u0441\u044f.
+PeersView.T.info=l (local - \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0435): \u0412\u0438 \u0437'\u0454\u0434\u043d\u0430\u043b\u0438\u0441\u044f, r (remote - \u0432\u0456\u0434\u0434\u0430\u043b\u0435\u043d\u0435): \u0443\u0447\u0430\u0441\u043d\u0438\u043a \u0437'\u0454\u0434\u043d\u0430\u0432\u0441\u044f.
 PeersView.T.L.tooltip=\u0412\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f
 PeersView.T.R.tooltip=\u0423\u0447\u0430\u0441\u043d\u0438\u043a \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f
-PeersView.I1=\u042f \u0437\u0430\u0446\u0456\u043a\u0430\u0432\u043b\u0435\u043d\u0438\u0439
-PeersView.I1.info=\u0412\u0438 \u0437\u0430\u0446\u0456\u043a\u0430\u0432\u043b\u0435\u043d\u0456 \u0432 \u0442\u043e\u043c\u0443, \u0449\u043e \u043c\u0430\u0454 \u0456\u043d\u0448\u0438\u0439 \u0441\u0456\u0434\u0435\u0440?
-PeersView.C1=C (\u0431\u043b\u043e\u043a\u043e\u0432\u0430\u043d\u0438\u0439 \u0442\u0438\u043c, \u0445\u0442\u043e \u043f\u0440\u0438\u0439\u043c\u0430\u0454)
-PeersView.C1.info=\u0417\u0430\u0431\u043e\u0440\u043e\u043d\u0430  \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437 \u0432\u0430\u0448\u043e\u0457 \u0441\u0442\u043e\u0440\u043e\u043d\u0438
+PeersView.I1=\u042f \u0437\u0430\u0446\u0456\u043a\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u043e\u043c
+PeersView.I1.info=\u0412\u0438 \u0437\u0430\u0446\u0456\u043a\u0430\u0432\u043b\u0435\u043d\u0456 \u0432 \u0442\u043e\u043c\u0443, \u0449\u043e \u043c\u0430\u0454 \u0456\u043d\u0448\u0438\u0439 \u0443\u0447\u0430\u0441\u043d\u0438\u043a?
+PeersView.C1=C (\u0431\u043b\u043e\u043a\u043e\u0432\u0430\u043d\u0438\u0439 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u043e\u043c)
+PeersView.C1.info=\u0417\u0430\u0431\u043e\u0440\u043e\u043d\u0430 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u043e\u043c
 PeersView.pieces=\u0427\u0430\u0441\u0442\u0438\u043d
 PeersView.downloadspeed=\u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 PeersView.download=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043e
-PeersView.I2=\u0412\u0456\u043d \u0437\u0430\u0446\u0456\u043a\u0430\u0432\u043b\u0435\u043d\u0438\u0439
-PeersView.I2.info=\u0427\u0438 \u0437\u0430\u0446\u0456\u043a\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u0456\u043d\u0448\u0438\u0439 \u0441\u0456\u0434\u0435\u0440 \u0432 \u0442\u043e\u043c\u0443, \u0449\u043e \u043c\u0430\u044e \u044f?
-PeersView.C2=C (\u0431\u043b\u043e\u043a\u043e\u0432\u0430\u043d\u0438\u0439)
-PeersView.C2.info=\u0417\u0430\u0431\u043e\u0440\u043e\u043d\u0438\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0443 \u043f\u0440\u0438\u0439\u043c\u0430\u044e\u0447\u0438\u043c
+PeersView.I2=\u0423\u0447\u0430\u0441\u043d\u0438\u043a \u0437\u0430\u0446\u0456\u043a\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u0412\u0430\u043c\u0438
+PeersView.I2.info=\u0427\u0438 \u0437\u0430\u0446\u0456\u043a\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u0456\u043d\u0448\u0438\u0439 \u0443\u0447\u0430\u0441\u043d\u0438\u043a \u0432 \u0442\u043e\u043c\u0443, \u0449\u043e \u043c\u0430\u044e \u044f?
+PeersView.C2=C (\u0431\u043b\u043e\u043a\u043e\u0432\u0430\u043d\u0438\u0439 \u0441\u0456\u0434\u0435\u0440\u043e\u043c)
+PeersView.C2.info=\u0417\u0430\u0431\u043e\u0440\u043e\u043d\u0438\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0443 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c
 PeersView.uploadspeed=\u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 PeersView.uploadspeed.info=\u0412\u0430\u0448\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 PeersView.upload=\u0420\u043e\u0437\u0434\u0430\u043d\u043e
-PeersView.upload.info=\u0412\u0430\u043c\u0438 \u0440\u043e\u0437\u0434\u0430\u043d\u043e \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0435\u0432\u0456.
+PeersView.upload.info=\u0412\u0430\u043c\u0438 \u0440\u043e\u0437\u0434\u0430\u043d\u043e \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0443.
 PeersView.statup=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
-PeersView.statup.info=\u041e\u0440\u0456\u0454\u043d\u0442\u043e\u0432\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430. 
-PeersView.S=\u0412\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044f
-PeersView.S.info=\u0411\u043b\u043e\u043a\u0443\u0432\u0430\u043d\u043d\u044f: \u041a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0432\u0440\u0443\u0447\u043d\u0443 \u0430\u0431\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e (\u0437\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0443 \u043d\u0430 \u0437\u0430\u043d\u0430\u0434\u0442\u043e \u043d\u0438\u0437\u044c\u043a\u0456\u0439 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456)
+PeersView.statup.info=\u041e\u0440\u0456\u0454\u043d\u0442\u043e\u0432\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
+PeersView.S=\u0412\u0438\u043d\u044f\u0442\u043e\u043a
+PeersView.S.info=\u0411\u043b\u043e\u043a\u0443\u0432\u0430\u043d\u043d\u044f: \u0423\u0447\u0430\u0441\u043d\u0438\u043a \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043d\u0438\u0439 \u0432\u0438\u043d\u044f\u0442\u043a\u043e\u043c \u0432\u0440\u0443\u0447\u043d\u0443 \u0430\u0431\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e (\u0437\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0443 \u043d\u0430 \u0437\u0430\u043d\u0438\u0437\u044c\u043a\u0456\u0439 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456)
 PeersView.downloadspeedoverall=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 PeersView.optunchoke=\u0420\u043e\u0437\u0431\u043b\u043e\u043a\u0443\u0432\u0430\u0442\u0438
 PeersView.client=\u041a\u043b\u0456\u0454\u043d\u0442
-PeersView.client.info=\u041d\u0430\u0437\u0432\u0430 BT-\u043a\u043b\u0456\u0454\u043d\u0442\u0430, \u044f\u043a\u0438\u0439 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0441\u0456\u0434\u0435\u0440\u043e\u043c
+PeersView.client.info=\u041d\u0430\u0437\u0432\u0430 BT-\u043a\u043b\u0456\u0454\u043d\u0442\u0430, \u044f\u043a\u0438\u0439 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u043e\u043c
 PeersView.menu.snubbed=\u041f\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 
 PeersView.title.short=\u0423\u0447\u0430\u0441\u043d\u0438\u043a\u0438
 PeersView.title.full=\u0423\u0447\u0430\u0441\u043d\u0438\u043a\u0438
 AllPeersView.title.full=\u0412\u0441\u0456 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0438
 ConfigView.section.files=\u0424\u0430\u0439\u043b\u0438
-ConfigView.label.usefastresume=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u043c\u0435\u0442\u043e\u0434 "\u0448\u0432\u0438\u0434\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u0432\u0436\u0435\u043d\u043d\u044f"
+ConfigView.label.usefastresume=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u043c\u0435\u0442\u043e\u0434 "\u0448\u0432\u0438\u0434\u043a\u043e\u0433\u043e" \u043f\u0440\u043e\u0434\u043e\u0432\u0436\u0435\u043d\u043d\u044f
 ConfigView.label.incrementalfile=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u0456\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0435 \u0441\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0456\u0432
 ConfigView.label.defaultsavepath=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0456\u0439 \u0442\u0435\u0446\u0456
-ConfigView.button.browse=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434...
-ConfigView.dialog.choosedefaultsavepath=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0442\u0435\u043a\u0443 \u0437\u0430\u043f\u0438\u0441\u0443 \u0434\u043b\u044f \u0432\u0441\u0456\u0445 \u0444\u0430\u0439\u043b\u0456\u0432
-ConfigView.section.server=\u0421\u0435\u0440\u0432\u0435\u0440
+ConfigView.button.browse=&\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434...
+ConfigView.dialog.choosedefaultsavepath=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0442\u0435\u043a\u0443 \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0441\u0456\u0445 \u0444\u0430\u0439\u043b\u0456\u0432
+ConfigView.section.server=\u0417'\u0454\u0434\u043d\u0430\u043d\u043d\u044f
 ConfigView.section.global=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0435
 ConfigView.label.disconnetseed=\u0412\u0456\u0434\u2019\u0454\u0434\u043d\u0443\u0432\u0430\u0442\u0438\u0441\u044f \u0432\u0456\u0434 \u0441\u0456\u0434\u0435\u0440\u0456\u0432 \u0443 \u0447\u0430\u0441 \u0432\u043b\u0430\u0441\u043d\u043e\u0457 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 ConfigView.label.switchpriority=\u0417\u043c\u0456\u043d\u0438\u0442\u0438 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 ConfigView.label.maxdownloads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
-ConfigView.label.maxdownloads.tooltip=\u0412\u0438 \u0437\u0430\u0432\u0436\u0434\u0438 \u0437\u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438 \u0446\u044e \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437 \u043e\u0434\u043d\u0438\u043c \u0432\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044f\u043c.\n\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442 \u0437 \u0432\u0438\u0449\u0438\u043c \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u043c\u043e\u0436\u0435 \u0442\u0430\u043a\u043e\u0436 \u0437\u0430\u0439\u043c\u0430\u0442\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u0438\u0439 \u0441\u043b\u043e\u0442 \u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443 \u043f\u043e\u0442\u0440\u0435\u0431\u0438.
+ConfigView.label.maxdownloads.tooltip=\u0412\u0438 \u0437\u0430\u0432\u0436\u0434\u0438 \u0437\u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438 \u0446\u044e \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437 \u043e\u0434\u043d\u0438\u043c \u0432\u0438\u043d\u044f\u0442\u043a\u043e\u043c.\n\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442 \u0437 \u0432\u0438\u0449\u0438\u043c \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u043c\u043e\u0436\u0435 \u0442\u0430\u043a\u043e\u0436 \u0437\u0430\u0439\u043c\u0430\u0442\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u0438\u0439 \u0441\u043b\u043e\u0442 \u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443 \u043f\u043e\u0442\u0440\u0435\u0431\u0438.
 ConfigView.label.maxactivetorrents=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0430\u043a\u0442\u0438\u0432\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0438\u0439]\n\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0430\u0431\u043e \u0440\u043e\u0437\u0434\u0430\u0447\u0430 \u043d\u043e\u0432\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u043d\u0435 \u043f\u043e\u0447\u0438\u043d\u0430\u0454\u0442\u044c\u0441\u044f,\n\u044f\u043a\u0449\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u043f\u0435\u0440\u0435\u0432\u0438\u0449\u0435\u043d\u0438\u0439.
-ConfigView.label.priorityExtensions=\u0420\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u043d\u044f \u0432\u0438\u0449\u043e\u0433\u043e \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443 (\u043d\u0430\u043f\u0440.: .jpg)
+ConfigView.label.priorityExtensions=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0440\u043e\u0437\u0442\u0430\u0448\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0437\u0430 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0438 \u0437 \u0440\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u043d\u044f\u043c\u0438 (\u043d\u0430\u043f\u0440.: .txt;.nfo;.jpg)
 ConfigView.section.transfer=\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430
-ConfigView.label.maxuploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0440\u043e\u0437\u0434\u0430\u0447\u0456
+ConfigView.label.maxuploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 ConfigView.label.maxuploadspeed=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u041a\u0431\u0456\u0442/\u0441 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
-ConfigView.label.saveresumeinterval=\u0417\u0430\u043f\u0438\u0441 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0434\u043b\u044f "\u0448\u0432\u0438\u0434\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u0432\u0436\u0435\u043d\u043d\u044f" \u043a\u043e\u0436\u043d\u0456
+ConfigView.label.saveresumeinterval=\u0417\u0430\u043f\u0438\u0441 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0434\u043b\u044f "\u0448\u0432\u0438\u0434\u043a\u043e\u0433\u043e" \u043f\u0440\u043e\u0434\u043e\u0432\u0436\u0435\u043d\u043d\u044f \u043a\u043e\u0436\u043d\u0456
 ConfigView.unlimited=\u041d\u0435 \u043e\u0431\u043c\u0435\u0436\u0443\u0432\u0430\u0442\u0438
 ConfigView.section.display=\u0417\u043e\u0432\u043d\u0456\u0448\u043d\u0456\u0439 \u0432\u0438\u0433\u043b\u044f\u0434
-ConfigView.label.opendetails=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u0437 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044f\u043c\u0438
+ConfigView.label.opendetails=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 \u0437 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044f\u043c\u0438
 ConfigView.label.openbar=\u0412\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0442\u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e
 ConfigView.label.use_old_speed_menus=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0441\u0442\u0430\u0440\u0438\u0439 \u0441\u0442\u0438\u043b\u044c \u0448\u0432\u0438\u0434\u043a\u0438\u0445 \u043c\u0435\u043d\u044e [\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443]
 ConfigView.label.closetotray=\u041f\u0440\u0438 \u0437\u0430\u043a\u0440\u0438\u0442\u0442\u0456 \u0437\u0433\u043e\u0440\u043d\u0443\u0442\u0438 \u0432 \u0442\u0440\u0435\u0439
@@ -156,20 +157,20 @@ ConfigView.label.autoupdate=\u0412\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u04
 ConfigView.label.openconsole=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443
 ConfigView.label.openconfig=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443
 ConfigView.label.startminimized=\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u0438 \u0432 \u0437\u0433\u043e\u0440\u043d\u0443\u0442\u043e\u043c\u0443 \u0432\u0456\u043a\u043d\u0456
-ConfigView.section.irc=IRC-\u043c\u0435\u0440\u0435\u0436\u0430
+ConfigView.section.irc=\u041c\u0435\u0440\u0435\u0436\u0430 IRC
 ConfigView.label.ircwiki=\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430: http://www.azureuswiki.com/index.php/IRC#Rules_for_IRC
 ConfigView.label.ircserver=\u0421\u0435\u0440\u0432\u0435\u0440
 ConfigView.label.ircchannel=\u041a\u0456\u043c\u043d\u0430\u0442\u0430
 ConfigView.label.irclogin=\u041d\u0456\u043a\u043d\u0435\u0439\u043c
 ConfigView.group.irctitle=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f IRC
-ConfigView.boolean.ircsendinfo=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0430\u043d\u043e\u043d\u0456\u043c\u043d\u0435 \u043f\u043e\u0448\u0438\u0440\u0435\u043d\u043d\u044f \u0432\u0430\u0448\u0438\u0445 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \n \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0449\u043e\u0431 \u0430\u0434\u043c\u0456\u043d\u0456\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0438 \u043a\u0430\u043d\u0430\u043b\u0443 \u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u043b\u0435\u0433\u0448\u0438\u0442\u0438 \u0432\u0430\u043c \u043f\u0440\u043e\u0446\u0435\u0441
+ConfigView.boolean.ircsendinfo=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0430\u043d\u043e\u043d\u0456\u043c\u043d\u0435 \u043f\u043e\u0448\u0438\u0440\u0435\u043d\u043d\u044f \u0432\u0430\u0448\u0438\u0445 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \n \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0449\u043e\u0431 \u0430\u0434\u043c\u0456\u043d\u0456\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0438 \u043a\u0430\u043d\u0430\u043b\u0443 \u043c\u043e\u0433\u043b\u0438 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u0442\u0438 \u0432\u0430\u043c
 ConfigView.boolean.irclog=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043b\u043e\u0433 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0456 IRC ( \u0443 \u0444\u0430\u0439\u043b IRC_log.htm)
 ConfigView.section.security=\u0411\u0435\u0437\u043f\u0435\u043a\u0430
-ConfigView.label.password=\u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u0443 \u0432 Vuze
+ConfigView.label.password=\u0417\u0430\u0445\u0438\u0441\u0442\u0438\u0442\u0438 Vuze, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0447\u0438 \u043f\u0430\u0440\u043e\u043b\u044c.\n - \u0432\u0456\u043d \u0431\u0443\u0434\u0435 \u0437\u0430\u043f\u0438\u0442\u0430\u043d\u0438\u0439 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u0430\u0431\u043e \u0437\u043c\u0456\u043d\u0456.
 ConfigView.label.passwordconfirm=\u041f\u0430\u0440\u043e\u043b\u044c (\u043f\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0436\u0435\u043d\u043d\u044f)
 ConfigView.label.passwordmatch=\u041f\u0430\u0440\u043e\u043b\u044c \u0430\u043a\u0442\u0438\u0432\u043d\u0438\u0439 :
 ConfigView.label.passwordmatchnone=\u041d\u0456
-ConfigView.label.passwordmatchno=\u041d\u0435\u043c\u0430\u0454 \u0430\u0431\u043e \u043f\u0430\u0440\u043e\u043b\u044c \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0438\u0439
+ConfigView.label.passwordmatchno=\u041d\u0435\u043c\u0430 \u0430\u0431\u043e \u043f\u0430\u0440\u043e\u043b\u044c \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0438\u0439
 ConfigView.label.passwordmatchyes=\u0422\u0430\u043a
 ConfigView.button.save=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438
 ConfigView.title.short=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f
@@ -220,18 +221,18 @@ GeneralView.label.seeds=\u0421\u0456\u0434\u0435\u0440\u0438:
 GeneralView.label.peers=\u0423\u0447\u0430\u0441\u043d\u0438\u043a\u0438:
 GeneralView.label.completed=\u0417\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043e: 
 GeneralView.label.totalspeed=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c : 
-GeneralView.label.totalspeed.tooltip=\u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456:
+GeneralView.label.totalspeed.tooltip=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0430 (\u0456 \u0441\u0435\u0440\u0435\u0434\u043d\u044f) \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0432\u0441\u0456\u0445 \u043a\u043b\u0456\u0454\u043d\u0442\u0456\u0432, \u0437 \u044f\u043a\u0438\u043c\u0438 \u0412\u0438 \u0437'\u0454\u0434\u043d\u0430\u043d\u0456.
 GeneralView.label.averagespeed=\u0441\u0435\u0440\u0435\u0434\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c
 GeneralView.label.filename=\u0406\u043c'\u044f \u0444\u0430\u0439\u043b\u0443:
 GeneralView.label.totalsize=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u043e\u0437\u043c\u0456\u0440 : 
-GeneralView.label.savein=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u0432 : 
+GeneralView.label.savein=\u0417\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0432 : 
 GeneralView.label.hash=\u0425\u0435\u0448 : 
 GeneralView.label.numberofpieces=\u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0447\u0430\u0441\u0442\u0438\u043d: 
 GeneralView.label.size=\u0420\u043e\u0437\u043c\u0456\u0440 : 
-GeneralView.label.tracker=\u0422\u0440\u0435\u043a\u0435\u0440 : 
+GeneralView.label.tracker=\u0421\u0442\u0430\u0442\u0443\u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0443 : 
 GeneralView.label.updatein=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 : 
-GeneralView.label.trackerurl=\u0422\u0440\u0435\u043a\u0435\u0440 URL :
-GeneralView.label.trackerurlupdate=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u0441\u0430\u043c\u043e\u0441\u0442\u0456\u0439\u043d\u043e
+GeneralView.label.trackerurl=\u0410\u0434\u0440\u0435\u0441\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 :
+GeneralView.label.trackerurlupdate=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u0442\u0440\u0435\u043a\u0435\u0440
 GeneralView.label.comment=\u041a\u043e\u043c\u0435\u043d\u0442\u0430\u0440 :
 GeneralView.label.user_comment=\u041a\u043e\u043c\u0435\u043d\u0442\u0430\u0440 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 : 
 GeneralView.label.status=\u0421\u0442\u0430\u0442\u0443\u0441 :
@@ -251,13 +252,13 @@ PiecesView.size=\u0420\u043e\u0437\u043c\u0456\u0440
 PiecesView.numberofblocks=\u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0431\u043b\u043e\u043a\u0456\u0432
 PiecesView.blocks=\u0411\u043b\u043e\u043a\u0438
 PiecesView.completed=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0430
-PiecesView.availability=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0456\u0441\u0442\u044c
+PiecesView.availability=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e
 PiecesView.reservedby=\u0417\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u043e\u0432\u0430\u043d\u0438\u0439
 PiecesView.writers=\u0411\u043b\u043e\u043a\u0443\u0432\u0430\u0442\u0438 \u043f\u043e\u043c\u0456\u0447\u043d\u0438\u043a\u0456\u0432
 PiecesView.title.short=\u0427\u0430\u0441\u0442\u0438\u043d\u0438
 PiecesView.title.full=\u0427\u0430\u0441\u0442\u0438\u043d\u0438
-SystemTray.tooltip.seeding=\u0440\u043e\u0437\u0434\u0430\u0447\u0430: %1, 
-SystemTray.tooltip.downloading=\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f: %1, 
+SystemTray.tooltip.seeding=\u0420\u043e\u0437\u0434\u0430\u0447\u0430: %1, 
+SystemTray.tooltip.downloading=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f: %1, 
 DownloadManager.error.filenotfound=\u0424\u0430\u0439\u043b \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u0438\u0439
 DownloadManager.error.fileempty=\u041f\u043e\u0440\u043e\u0436\u043d\u0456\u0439 \u0442\u043e\u0440\u0435\u043d\u0442
 DownloadManager.error.filetoobig=\u0422\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b \u0437\u0430\u043d\u0430\u0434\u0442\u043e \u0432\u0435\u043b\u0438\u043a\u0438\u0439
@@ -266,17 +267,17 @@ DownloadManager.error.unsupportedencoding=\u041a\u043e\u0434\u0443\u0432\u0430\u
 DownloadManager.error.ioerror=IO-\u043f\u043e\u043c\u0438\u043b\u043a\u0430
 DownloadManager.error.sha1="\u0410\u043b\u0433o\u0440\u0438\u0442\u043c (SHA1) \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u0438\u0439"- \u043f\u043e\u043c\u0438\u043b\u043a\u0430
 PeerManager.status.offline=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f
-PeerManager.status.ok=\u041e\u041a
+PeerManager.status.ok=\u0413\u0430\u0440\u0430\u0437\u0434
 PeerManager.status.checking=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430
 PeerManager.status.finished=\u0413\u043e\u0442\u043e\u0432\u043e
 PeerManager.status.finishedin=\u0417\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043e \u0437\u0430
-MainWindow.upgrade.assistant=\u041e\u043d\u043e\u0432\u0438\u0442\u0438
-MainWindow.upgrade.newerversion=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u043e\u0432\u0430 \u0432\u0435\u0440\u0441\u0456\u044f, \u043e\u043d\u043e\u0432\u0438\u0442\u0438?
+MainWindow.upgrade.assistant=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438
+MainWindow.upgrade.newerversion=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u043e\u0432\u0430 \u0432\u0435\u0440\u0441\u0456\u044f, \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0438?
 MainWindow.upgrade.explanation=Vuze \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u044c \u043d\u043e\u0432\u0443 \u0432\u0435\u0440\u0441\u0456\u044e \u0456 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f
 MainWindow.upgrade.explanation.manual=\u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0443 \u0441\u0430\u043c\u043e\u0441\u0442\u0456\u0439\u043d\u043e: \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0442\u0435 \u043d\u043e\u0432\u0443 \u0432\u0435\u0440\u0441\u0456\u044e \u0456 \u0437\u0430\u043f\u0443\u0441\u0442\u0456\u0442\u044c \u0437\u043d\u043e\u0432\u0443 Vuze
 MainWindow.upgrade.step1=\u041a\u0440\u043e\u043a 1: \u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0442\u0435 \u043d\u043e\u0432\u0443 \u0432\u0435\u0440\u0441\u0456\u044e
 MainWindow.upgrade.step2=\u041a\u0440\u043e\u043a 2: \u0417\u0430\u043f\u0443\u0441\u0442\u0456\u0442\u044c \u0437\u043d\u043e\u0432\u0443 Vuze
-MainWindow.upgrade.hint1=\u041f\u043e\u0440\u0430\u0434\u0430:\t\u041f\u0440\u0438 \u043d\u0430\u0442\u0438\u0441\u043a\u0430\u043d\u043d\u0456 \u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0438 \u0432\u0441\u0435 \u0431\u0443\u0434\u0435 \u0437\u0440\u043e\u0431\u043b\u0435\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e
+MainWindow.upgrade.hint1=\u041f\u043e\u0440\u0430\u0434\u0430:\t\u041f\u0440\u0438 \u043d\u0430\u0442\u0438\u0441\u043a\u0430\u043d\u043d\u0456 \u0417\u0430\u043a\u0456\u043d\u0447\u0438\u0442\u0438 \u0432\u0441\u0435 \u0431\u0443\u0434\u0435 \u0437\u0440\u043e\u0431\u043b\u0435\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e
 MainWindow.upgrade.hint2=\u041f\u043e\u0440\u0430\u0434\u0430:\t\u042f\u043a\u0449\u043e \u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0430\u043a\u0440\u0438\u0442\u0438 Vuze \u043f\u0456\u0437\u043d\u0456\u0448\u0435, \u043d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438 \u0456\n\t\u043f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0439\u0442\u0435 \u0444\u0430\u0439\u043b Azureus2-new.jar \u0432 Azureus2.jar \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u043a\u0440\u0438\u0442\u0442\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438
 MainWindow.upgrade.error.downloading.hint=\u041f\u043e\u043c\u0438\u043b\u043a\u0430:\t\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 \u043d\u0435 \u0437\u043c\u043e\u0433\u043b\u0430 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u043d\u043e\u0432\u0443 \u0432\u0435\u0440\u0441\u0456\u044e
 MainWindow.upgrade.section.info=\u041d\u043e\u0432\u0430 \u0432\u0435\u0440\u0441\u0456\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
@@ -312,12 +313,12 @@ IrcView.privateto=\u0414\u043b\u044f
 IrcView.privatefrom=\u0412\u0456\u0434 
 IrcView.noticefrom=\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430 : 
 IrcView.errormsg=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0438\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0432 /msg : /msg \u0432\u0430\u0448 \u0442\u0435\u043a\u0441\u0442
-IrcView.help=\u0414\u0456\u044e\u0447\u0456 \u043a\u043e\u043c\u0430\u043d\u0434\u0438: \n/help : \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0446\u0435\u0439 \u0442\u0435\u043a\u0441\u0442\n/nick | /name : \u0437\u043c\u0456\u043d\u0438\u0442\u0438 \u0441\u0432\u0456\u0439 \u043d\u0456\u043a\n/me action : \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u0442\u0438 \u043f\u0440\u0438\u043c\u0456\u0442\u043a\u0443\n/msg: \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u0442\u0438 \u043e\u0441\u043e\u0431\u0438\u0441\u0442\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f <\u043d\u0456\u043a>\n/r message : \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0441\u0442\u0438 \u043d\u0430 \u043e\u0441\u043e\u0431\u0438\u0441\u0442\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f\n/join #\u043a\u0456\u043c\u043d\u0430\u0442\u0430 : \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u0456\u043d\u0448\u0443 \u043a\u0456\u043c\u043d\u0430\u0442\u0443
+IrcView.help=\u0427\u0438\u043d\u043d\u0456 \u043a\u043e\u043c\u0430\u043d\u0434\u0438: \n/help : \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0446\u0435\u0439 \u0442\u0435\u043a\u0441\u0442\n/nick | /name : \u0437\u043c\u0456\u043d\u0438\u0442\u0438 \u0441\u0432\u0456\u0439 \u043d\u0456\u043a\n/me action : \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u0442\u0438 \u043f\u0440\u0438\u043c\u0456\u0442\u043a\u0443\n/msg: \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u0442\u0438 \u043e\u0441\u043e\u0431\u0438\u0441\u0442\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f <\u043d\u0456\u043a>\n/r message : \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0441\u0442\u0438 \u043d\u0430 \u043e\u0441\u043e\u0431\u0438\u0441\u0442\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f\n/join #channelB (\u043d\u0435 \u043a\u043b\u0430\u0446\u0430\u0439\u0442\u0435, \u0446\u0435 \u043f\u0440\u0438\u043a\u043b\u0430\u0434) : \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u0456\u043d\u0448\u0443 \u043a\u0456\u043c\u043d\u0430\u0442\u0443
 PasswordWindow.title=Vuze \u0431\u043b\u043e\u043a\u043e\u0432\u0430\u043d\u0438\u0439
-PasswordWindow.passwordprotected=Vuze \u0437\u0430\u0445\u0438\u0449\u0435\u043d\u0438\u0439 \u043f\u0430\u0440\u043e\u043b\u0435\u043c.\n\u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0443 \u0434\u043e \u0432\u0456\u043a\u043d\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u0432\u043a\u0430\u0436\u0456\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c :
+PasswordWindow.passwordprotected=Vuze \u0437\u0430\u0445\u0438\u0449\u0435\u043d\u0438\u0439 \u043f\u0430\u0440\u043e\u043b\u0435\u043c.\n\u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0443 \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u0432\u043a\u0430\u0436\u0456\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c :
 Button.ok=&O\u041a 
 TrackerChangerWindow.title=\u0417\u0430\u043c\u0456\u043d\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0443
-TrackerChangerWindow.newtracker=\u0412\u043a\u0430\u0436\u0456\u0442\u044c URL \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0440\u0435\u043a\u0435\u0440\u0443
+TrackerChangerWindow.newtracker=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u0430\u0434\u0440\u0435\u0441\u0443 \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0440\u0435\u043a\u0435\u0440\u0443
 PeersView.discarded=\u0412\u0456\u0434\u0445\u0438\u043b\u0435\u043d\u0438\u0439
 PeersView.discarded.info=\u0421\u0442\u0435\u0440\u0442\u0456 \u0434\u0430\u043d\u0456, \u044f\u043a\u0456 \u0412\u0430\u043c \u043d\u0435 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0456
 discarded=\u0432\u0456\u0434\u0445\u0438\u043b\u0435\u043d\u043e
@@ -330,7 +331,7 @@ ConfigView.section.downloadManagement=\u041c\u0435\u043d\u0435\u0434\u0436\u043c
 ConfigView.label.startRatioPeers=\u041f\u043e\u0447\u0430\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0443 \u043f\u0440\u0438 \u043a\u0456\u043b\u044c\u043a\u043e\u0441\u0442\u0456 \u0441\u0456\u0434\u0435\u0440\u0456\u0432 \u043c\u0435\u043d\u0448\u0435 1
 ConfigView.text.neverStop=\u041d\u0456\u043a\u043e\u043b\u0438 \u043d\u0435 \u0437\u0443\u043f\u0438\u043d\u044f\u0442\u0438
 ConfigView.text.neverStart=\u041d\u0456\u043a\u043e\u043b\u0438 \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u0438
-ConfigView.text.peers=\u0423\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432
+ConfigView.text.peers=\u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432
 ConfigView.label.checkOncompletion=\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0438\u0439 \u043e\u0433\u043b\u044f\u0434 \u0447\u0430\u0441\u0442\u0438\u043d \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 wizard.title=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442
 wizard.previous=< \u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438\u0441\u044f
@@ -338,7 +339,7 @@ wizard.next=\u0414\u0430\u043b\u0456 >
 wizard.finish=\u0413\u043e\u0442\u043e\u0432\u043e
 wizard.mode=\u0422\u0440\u0435\u043a\u0435\u0440 / \u0420\u0435\u0436\u0438\u043c
 wizard.tracker=\u0422\u0440\u0435\u043a\u0435\u0440:
-wizard.invalidurl=\u041f\u043e\u043c\u0438\u043b\u043a\u043e\u0432\u0430 URL
+wizard.invalidurl=\u041f\u043e\u043c\u0438\u043b\u043a\u043e\u0432\u0430 \u0430\u0434\u0440\u0435\u0441\u0430
 wizard.singlefile=\u041e\u0434\u0438\u043d \u0444\u0430\u0439\u043b
 wizard.singlefile.help=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0443
 wizard.directory=\u0422\u0435\u043a\u0430
@@ -354,7 +355,7 @@ wizard.choosetorrent=\u0412\u0438\u0431\u0456\u0440 torrent-\u0444\u0430\u0439\u
 wizard.information=\u0406\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f
 wizard.notimplemented=\u0429\u0435 \u0432 \u0440\u043e\u0437\u0440\u043e\u0431\u0446\u0456
 wizard.progresstitle=\u0421\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443
-wizard.savingfile=\u0417\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443 ...
+wizard.savingfile=\u0417\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443...
 wizard.filesaved=\u0424\u0430\u0439\u043b \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0438\u0439.
 wizard.close=\u0417\u0430\u043a\u0440\u0438\u0442\u0438
 Torrent.create.progress.piecelength=\u0414\u043e\u0432\u0436\u0438\u043d\u0430 \u0447\u0430\u0441\u0442\u0438\u043d:
@@ -363,12 +364,12 @@ Torrent.create.progress.totalfilesize=\u0417\u0430\u0433\u0430\u043b\u044c\u043d
 Torrent.create.progress.totalfilecount=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0444\u0430\u0439\u043b\u0456\u0432:
 Torrent.create.progress.parsingfiles=\u041f\u0430\u0440\u0441\u0456\u043d\u0433 \u0444\u0430\u0439\u043b\u0443
 Torrent.create.progress.hashing=\u0425\u0435\u0448\u0443\u0432\u0430\u043d\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0456\u0432
-MainWindow.upgrade.downloadingfrom=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0437 :
-MainWindow.menu.view.ipFilter=\u0424\u0456\u043b\u044c\u0442\u0440\u0438 &IP
+MainWindow.upgrade.downloadingfrom=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437 :
+MainWindow.menu.view.ipFilter=&\u0424\u0456\u043b\u044c\u0442\u0440\u0438 IP
 ConfigView.section.ipfilter=\u0424\u0456\u043b\u044c\u0442\u0440\u0438 IP
 ConfigView.section.ipfilter.description=\u041e\u043f\u0438\u0441
-ConfigView.section.ipfilter.start=\u041f\u043e\u0447\u0430\u0442\u043a\u043e\u0432\u0438\u0439 IP
-ConfigView.section.ipfilter.end=\u041a\u0456\u043d\u0446\u0435\u0432\u0438\u0439 IP
+ConfigView.section.ipfilter.start=\u041f\u043e\u0447\u0430\u0442\u043a\u043e\u0432\u0430 IP
+ConfigView.section.ipfilter.end=\u041a\u0456\u043d\u0446\u0435\u0432\u0430 IP
 ConfigView.section.ipfilter.add=\u0414\u043e\u0434\u0430\u0442\u0438
 ConfigView.section.ipfilter.remove=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438
 ConfigView.section.ipfilter.edit=\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438
@@ -385,15 +386,15 @@ ConfigView.label.seeds=\u0441\u0456\u0434\u0435\u0440\u0456\u0432
 ConfigView.section.seeding=\u0420\u043e\u0437\u0434\u0430\u0447\u0430
 MyTorrentsView.menu.removeand=\u0412\u0438\u043b\u0443&\u0447\u0438\u0442\u0438 \u0456
 MyTorrentsView.menu.removeand.deletetorrent=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 &\u0442\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b
-MyTorrentsView.menu.removeand.deletedata=&\u0421\u0442\u0435\u0440\u0442\u0438 \u0444\u0430\u0439\u043b\u0438
-MyTorrentsView.menu.removeand.deleteboth=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u043e\u0431\u0438\u0434\u0432\u0430
-deletedata.title=\u0423\u0432\u0430\u0433\u0430
-deletedata.message1=\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0412\u0438 \u0437\u0431\u0438\u0440\u0430\u0454\u0442\u0435\u0441\u044f \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0434\u0430\u043d\u0456?
+MyTorrentsView.menu.removeand.deletedata=&\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0444\u0430\u0439\u043b\u0438
+MyTorrentsView.menu.removeand.deleteboth=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0456 \u0437\u0430\u0432\u0430\u043d\u0442., \u0456 \u0442\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b\u0438
+deletedata.title=\u0412\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457
+deletedata.message1=\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0412\u0438 \u0437\u0431\u0438\u0440\u0430\u0454\u0442\u0435\u0441\u044f \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 '%1'?
 deletedata.noprompt=\u0411\u0456\u043b\u044c\u0448\u0435 \u043c\u0435\u043d\u0435 \u043d\u0435 \u0442\u0443\u0440\u0431\u0443\u0432\u0430\u0442\u0438
-MainWindow.menu.file.configure=\u041c\u0430\u0439\u0441\u0442\u0435\u0440 &\u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c
+MainWindow.menu.file.configure=&\u041c\u0430\u0439\u0441\u0442\u0435\u0440 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c
 configureWizard.title=\u041c\u0430\u0439\u0441\u0442\u0435\u0440 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c
 configureWizard.welcome.title=\u041b\u0430\u0441\u043a\u0430\u0432\u043e \u043f\u0440\u043e\u0441\u0438\u043c\u043e \u0432 \u043c\u0430\u0439\u0441\u0442\u0435\u0440 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c Vuze
-configureWizard.welcome.message=\u0426\u0435\u0439 \u043c\u0430\u0439\u0441\u0442\u0435\u0440 \u0434\u043e\u043f\u043e\u043c\u043e\u0436\u0435 \u0432\u0430\u043c \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0438\u0442\u0438 Vuze \u0434\u043b\u044f \u0437\u0440\u0443\u0447\u043d\u0456\u0448\u043e\u0433\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f. \u0414\u043b\u044f \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u0456\u0448\u043e\u0433\u043e \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0439\u0442\u0435 \u043c\u0435\u043d\u044e \u0406\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438 > \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f...
+configureWizard.welcome.message=\u0426\u0435\u0439 \u043c\u0430\u0439\u0441\u0442\u0435\u0440 \u0434\u043e\u043f\u043e\u043c\u043e\u0436\u0435 \u0412\u0430\u043c \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0438\u0442\u0438 Vuze \u0434\u043b\u044f \u0437\u0440\u0443\u0447\u043d\u0456\u0448\u043e\u0433\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f. \u0414\u043b\u044f \u0434\u043e\u043a\u043b\u0430\u0434\u043d\u0456\u0448\u043e\u0433\u043e \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0439\u0442\u0435 \u043c\u0435\u043d\u044e \u0421\u0435\u0440\u0432\u0456\u0441 > \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f...
 configureWizard.transfer.title=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0456 \u0434\u0430\u043d\u0438\u0445 \u0456 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c
 configureWizard.transfer.hint=\u041f\u043e\u0440\u0430\u0434\u0430: \t\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u0442\u044c\u0441\u044f \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456, \u0442\u0440\u043e\u0445\u0438 \u043c\u0435\u043d\u0448\u043e\u0457 \u0437\u0430 \u0432\u0430\u0448\u0443 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 configureWizard.transfer.message=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u0456 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f. \u0412\u0456\u0437\u044c\u043c\u0456\u0442\u044c \u0434\u043e \u0443\u0432\u0430\u0433\u0438, \u0449\u043e \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0432\u0456\u0434\u0431\u0438\u0432\u0430\u0454\u0442\u044c\u0441\u044f \u0432 \u043f\u043e\u0432\u0456\u043b\u044c\u043d\u0456\u0448\u0456\u0439 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f. \u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0432\u0440\u0430\u0445\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0437 \u043a\u043e\u0436\u043d\u0438\u043c \u0442\u043e\u0440\u0435\u043d\u0442\u043e\u043c, \u044f\u043a\u0438\u0439 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0454\u0442\u044c\u0441\u044f: \u0441\u043f\u0440\u043e\u0431\u0430 \u043e\u0434\u043d\u043e\u0447\u0430\u0441\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437\u0430\u043d\u0430\u0434\u0442\u043e \u0432\u0435\u043b\u0438\u043a\u043e\u0457 \u043a\u0456\u043b\u044c\u043a\u043e\u0441\u0442\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0441\u043f\u0440\u0438\u0447\u0438\u043d\u044f\u0454 \u043f\u043e\u0432\u0456\u043b\u044c\u043d\u0443 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c. \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u0442\u044c\u0441\u044f \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 5 \u041a\u0431\u0456\u0442/\u0441 \u043d\u0430 \u043a\u043e\u0436\u0435\u043d \u0442\u043e\u0440\u0435\u043d\u0442 \u044f\u043a \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u0438\u0439 \u043c\u0456\u043d\u0456\u043c\u0443\u043c. \u0427\u0438\u043c \u0432\u0438\u0449\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u0442\u0438\u043c \u0431\u0456\u043b\u044c\u0448\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f (\u0437\u0430\u043b\u0435\u0436\u043d\u043e \u0432\u0456\u0434 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0430).
@@ -407,35 +408,35 @@ configureWizard.transfer.connection.5=\u0410\u0414\u0421\u041b/\u041a\u0430\u043
 configureWizard.transfer.connection.6=\u0410\u0414\u0421\u041b/\u041a\u0430\u0431\u0435\u043b\u044c xxx/768 \u041a\u0431\u0456\u0442/\u0441 
 configureWizard.transfer.connection.7=\u0410\u0414\u0421\u041b/\u041a\u0430\u0431\u0435\u043b\u044c xxx/1024 \u041a\u0431\u0456\u0442/\u0441 
 configureWizard.transfer.maxUpSpeed=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u041a\u0431\u0456\u0442/\u0441
-configureWizard.transfer.maxActiveTorrents=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0434\u0456\u044e\u0447\u0438\u0445
+configureWizard.transfer.maxActiveTorrents=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a-\u0442\u044c \u0447\u0438\u043d\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
 configureWizard.transfer.maxDownloads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c
 configureWizard.transfer.maxUploadsPerTorrent=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
 configureWizard.nat.title=NAT / \u041f\u043e\u0440\u0442\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430
-configureWizard.nat.message=\u0414\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u043c\u043e\u0436\u043b\u0438\u0432\u043e\u0441\u0442\u0435\u0439 BitTorrent \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u0442\u044c\u0441\u044f \u043f\u043e\u0432\u043d\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u0434\u043e \u0406\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0443. \u0417\u0432\u0438\u0447\u0430\u0439\u043d\u043e \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0431\u0435\u0440\u0443\u0442\u044c\u0441\u044f \u043f\u043e\u0440\u0442\u0438 \u0437 6881 \u0434\u043e 6889. \u0426\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 \u043c\u043e\u0436\u0435 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u0438 \u0456, \u044f\u043a\u0449\u043e \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e, \u0437\u043c\u0456\u043d\u0438\u0442\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0456 \u043f\u043e\u0440\u0442\u0438. \u041f\u0456\u0434 \u0447\u0430\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0434\u0435\u044f\u043a\u0456 \u043f\u043e\u0440\u0442\u0438 \u043c\u043e\u0436\u0443\u0442\u044c \u0431\u0443\u0442\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456.
+configureWizard.nat.message=\u0414\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u043c\u043e\u0436\u043b\u0438\u0432\u043e\u0441\u0442\u0435\u0439 Vuze \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u0442\u044c\u0441\u044f \u043f\u043e\u0432\u043d\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u0434\u043e \u0406\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0443. \u0417\u0432\u0438\u0447\u0430\u0439\u043d\u043e \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0431\u0435\u0440\u0443\u0442\u044c\u0441\u044f \u043f\u043e\u0440\u0442\u0438 \u0437 6881 \u0434\u043e 6889. \u0426\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 \u043c\u043e\u0436\u0435 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u0438 \u0456, \u044f\u043a\u0449\u043e \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e, \u0437\u043c\u0456\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0456 \u043f\u043e\u0440\u0442\u0438. \u041f\u0456\u0434 \u0447\u0430\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0434\u0435\u044f\u043a\u0456 \u043f\u043e\u0440\u0442\u0438 \u043c\u043e\u0436\u0443\u0442\u044c \u0431\u0443\u0442\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456, \u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434, 6880.
 configureWizard.nat.test=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430
 configureWizard.nat.testing=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u043f\u043e\u0440\u0442\u0443
 configureWizard.nat.ko=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 NAT
 configureWizard.nat.unable=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u0438 \u043d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u043e. \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0456 \u043f\u043e\u0440\u0442 \u0430\u0431\u043e \u0441\u043b\u0443\u0436\u0431\u0430 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438.
 configureWizard.file.title=\u0422\u043e\u0440\u0435\u043d\u0442\u0438 / \u0424\u0430\u0439\u043b\u0438
 configureWizard.file.message1=\u0417\u0430\u043f\u0438\u0441 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0443 \u0437\u0430\u0434\u0430\u043d\u0456\u0439 \u0442\u0435\u0446\u0456. \u0412\u0438\u0431\u0456\u0440:
-configureWizard.file.path=\u041f\u0430\u043f\u043a\u0430
+configureWizard.file.path=\u0422\u0435\u043a\u0430
 configureWizard.file.browse=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434
 configureWizard.file.message2=Vuze \u043c\u0430\u0454 \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c \u043d\u0435\u0433\u0430\u0439\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u0432\u0436\u0435\u043d\u043d\u044f \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u0434\u043e\u0434\u0430\u0432\u0430\u043d\u043d\u044f \u043f\u0435\u0432\u043d\u0438\u0445 \u0434\u0430\u043d\u0438\u0445 \u0434\u043e \u0432\u0430\u0448\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432. \u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0447\u0438 \u0446\u044e \u0444\u0443\u043d\u043a\u0446\u0456\u044e, \u0454 \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c \u0434\u043e\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u043d\u0435 \u043f\u043e\u0432\u043d\u0456\u0441\u0442\u044e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0445 \u0447\u0430\u0441\u0442\u0438\u043d.
-configureWizard.file.fastResume=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0456\u044e "\u0448\u0432\u0438\u0434\u043a\u043e\u0433\u043e" \u043f\u0440\u043e\u0434\u043e\u0432\u0436\u0435\u043d\u043d\u044f
+configureWizard.file.fastResume=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 "\u0448\u0432\u0438\u0434\u043a\u0435" \u043f\u0440\u043e\u0434\u043e\u0432\u0436\u0435\u043d\u043d\u044f
 configureWizard.file.invalidPath=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430 \u0442\u0435\u043a\u0430
 configureWizard.finish.title=\u0413\u043e\u0442\u043e\u0432\u043e
-configureWizard.finish.message=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u043b\u043e\u0441\u044f. \u0411\u0430\u0436\u0430\u0454\u043c\u043e \u0432\u0430\u043c \u0432\u0434\u0430\u043b\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0447\u0430\u0441!
+configureWizard.finish.message=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u043b\u043e\u0441\u044f. \u0411\u0430\u0436\u0430\u0454\u043c\u043e \u0412\u0430\u043c \u0432\u0434\u0430\u043b\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0447\u0430\u0441!
 wizard.close.confirmation=\u041f\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0436\u0435\u043d\u043d\u044f
 wizard.close.message=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u043c\u0430\u0439\u0441\u0442\u0435\u0440 \u043f\u0440\u0438 \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u043e\u043c\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438?
-exportTorrentWizard.title=\u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
+exportTorrentWizard.title=\u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u0442\u043e\u0440\u0435\u043d\u0442\u0443 \u0432 \u0444\u0430\u0439\u043b XML
 exportTorrentWizard.torrentfile.title=\u0412\u0438\u0431\u0456\u0440 \u0432\u0445\u0456\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 exportTorrentWizard.torrentfile.message=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0442\u043e\u0440\u0435\u043d\u0442 \u0434\u043b\u044f \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u0443
-exportTorrentWizard.torrentfile.path=\u041f\u0430\u043f\u043a\u0430
+exportTorrentWizard.torrentfile.path=\u0428\u043b\u044f\u0445
 exportTorrentWizard.torrentfile.browse=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434
 exportTorrentWizard.torrentfile.invalidPath=\u041f\u043e\u043c\u0438\u043b\u043a\u043e\u0432\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442
 exportTorrentWizard.exportfile.title=\u0412\u0438\u0431\u0456\u0440 \u0444\u0430\u0439\u043b\u0443 \u0434\u043b\u044f \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u0443
-exportTorrentWizard.exportfile.message=\u0412\u043a\u0430\u0436\u0456\u0442\u044c XML-\u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u0443
-exportTorrentWizard.exportfile.path=\u041f\u0430\u043f\u043a\u0430
+exportTorrentWizard.exportfile.message=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u0444\u0430\u0439\u043b XML \u0434\u043b\u044f \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u0443
+exportTorrentWizard.exportfile.path=\u0428\u043b\u044f\u0445
 exportTorrentWizard.exportfile.browse=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434
 exportTorrentWizard.exportfile.invalidPath=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u0443 \u0444\u0430\u0439\u043b\u0456 \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u0443
 exportTorrentWizard.finish.title=\u0413\u043e\u0442\u043e\u0432\u043e
@@ -443,35 +444,35 @@ exportTorrentWizard.finish.message=\u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u
 exportTorrentWizard.process.inputfilebad.title=\u041f\u043e\u043c\u0438\u043b\u043a\u043e\u0432\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442
 exportTorrentWizard.process.inputfilebad.message=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0434\u043e\u0441\u0442\u0443\u043f\u0443 \u0434\u043e \u0432\u0445\u0456\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0443:
 exportTorrentWizard.process.outputfileexists.title=\u0424\u0430\u0439\u043b \u0432\u0436\u0435 \u0456\u0441\u043d\u0443\u0454
-exportTorrentWizard.process.outputfileexists.message=\u0424\u0430\u0439\u043b \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0443 \u0432\u0436\u0435 \u0456\u0441\u043d\u0443\u0454 - \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u0438?
+exportTorrentWizard.process.outputfileexists.message=\u0424\u0430\u0439\u043b \u0432\u0436\u0435 \u0456\u0441\u043d\u0443\u0454 - \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u0438?
 exportTorrentWizard.process.torrentfail.title=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u0447\u0438\u0442\u0430\u043d\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 exportTorrentWizard.process.exportfail.title=\u041d\u0435\u0432\u0434\u0430\u043b\u0438\u0439 \u0435\u043a\u0441\u043f\u043e\u0440\u0442 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
-exportTorrentWizard.process.unknownfail.title=\u041d\u0435\u0441\u043f\u043e\u0434\u0456\u0432\u0430\u043d\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430
-importTorrentWizard.title=XML-\u0456\u043c\u043f\u043e\u0440\u0442 \u0444\u0430\u0439\u043b\u0443
+exportTorrentWizard.process.unknownfail.title=\u041d\u0435\u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430
+importTorrentWizard.title=\u0406\u043c\u043f\u043e\u0440\u0442 \u0442\u043e\u0440\u0435\u043d\u0442\u0443 XML
 importTorrentWizard.torrentfile.title=\u0412\u0438\u0431\u0456\u0440 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
 importTorrentWizard.torrentfile.message=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u0456\u043c\u2019\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443 \u0434\u043b\u044f \u0456\u043c\u043f\u043e\u0440\u0442\u0443
-importTorrentWizard.torrentfile.path=\u041f\u0430\u043f\u043a\u0430
+importTorrentWizard.torrentfile.path=\u0428\u043b\u044f\u0445
 importTorrentWizard.torrentfile.browse=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434
 importTorrentWizard.torrentfile.invalidPath=\u041f\u043e\u043c\u0438\u043b\u043a\u043e\u0432\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442
 importTorrentWizard.importfile.title=\u0412\u0438\u0431\u0456\u0440 \u0444\u0430\u0439\u043b\u0443 \u0456\u043c\u043f\u043e\u0440\u0442\u0443
 importTorrentWizard.importfile.message=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0456\u043c\u043f\u043e\u0440\u0442\u0443
-importTorrentWizard.importfile.path=\u041f\u0430\u043f\u043a\u0430
+importTorrentWizard.importfile.path=\u0428\u043b\u044f\u0445
 importTorrentWizard.importfile.browse=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434
 importTorrentWizard.importfile.invalidPath=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u0444\u0430\u0439\u043b\u0443 \u0456\u043c\u043f\u043e\u0440\u0442\u0443
 importTorrentWizard.finish.title=\u041f\u0440\u043e\u0446\u0435\u0441 \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0438\u0439
 importTorrentWizard.finish.message=\u0406\u043c\u043f\u043e\u0440\u0442 \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0438\u0439 \u0432\u0434\u0430\u043b\u043e
 importTorrentWizard.process.inputfilebad.title=\u0406\u043c\u043f\u043e\u0440\u0442\u043e\u0432\u0430\u043d\u0438\u0439 \u0444\u0430\u0439\u043b \u043f\u043e\u043c\u0438\u043b\u043a\u043e\u0432\u0438\u0439
 importTorrentWizard.process.inputfilebad.message=\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0456:
-importTorrentWizard.process.outputfileexists.title=\u0424\u0430\u0439\u043b \u0443\u0436\u0435 \u0456\u0441\u043d\u0443\u0454
-importTorrentWizard.process.outputfileexists.message=\u0424\u0430\u0439\u043b \u0434\u043b\u044f \u0435\u043a\u0441\u043f\u043e\u0440\u0442\u0443 \u0432\u0436\u0435 \u0456\u0441\u043d\u0443\u0454 - \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u0438?
+importTorrentWizard.process.outputfileexists.title=\u0424\u0430\u0439\u043b \u0432\u0436\u0435 \u0456\u0441\u043d\u0443\u0454
+importTorrentWizard.process.outputfileexists.message=\u0424\u0430\u0439\u043b \u0432\u0436\u0435 \u0456\u0441\u043d\u0443\u0454 - \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u0438?
 importTorrentWizard.process.torrentfail.title=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 importTorrentWizard.process.importfail.title=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u043e \u0456\u043c\u043f\u043e\u0440\u0442\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
-importTorrentWizard.process.unknownfail.title=\u041d\u0435\u0441\u043f\u043e\u0434\u0456\u0432\u0430\u043d\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430
+importTorrentWizard.process.unknownfail.title=\u041d\u0435\u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430
 ConfigView.label.bindip=\u041f\u0440\u0438\u0432'\u044f\u0437\u0430\u0442\u0438 \u0434\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0457 IP-\u0430\u0434\u0440\u0435\u0441\u0438
 ConfigView.label.xfs.allocation=\u0420\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u044f\u0442\u0438 \u043d\u043e\u0432\u0456 \u0444\u0430\u0439\u043b\u0438, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0447\u0438 \u043c\u0435\u0442\u043e\u0434, \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u0438\u0439 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432\u0438\u0445 \u0441\u0438\u0441\u0442\u0435\u043c XFS 
 ConfigView.label.xfs.allocation.tooltip=\u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u043f\u0435\u0440\u0435\u043a\u043e\u043d\u0430\u0439\u0442\u0435\u0441\u044f \u0449\u043e /usr/sbin/xfs_io \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u0443 \u0432\u0430\u0448\u0456\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0456. \u041d\u0430 \u0431\u0430\u0433\u0430\u0442\u044c\u043e\u0445 Linux'\u0430\u0445 \u0432\u0436\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u043d\u0456\u0439 \u0432 \u043f\u0430\u043a\u0435\u0442\u0456 "xfsprogs".
 xfs.allocation.xfs_io.not.found=XFS-\u0440\u043e\u0437\u043c\u0456\u0449\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443 \u043d\u0435 \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u0435, \u0442\u043e\u043c\u0443 \u0449\u043e /usr/sbin/xfs_io \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0438\u043a\u043e\u043d\u0443\u0432\u0430\u043d\u0438\u043c. \u041f\u0435\u0440\u0435\u043a\u043e\u043d\u0430\u0439\u0441\u044f, \u0449\u043e \u0432\u043e\u043d\u043e \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0456. \u041a\u0456\u043d\u0446\u0435\u0432\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430: "%1".
-ConfigView.label.zeronewfiles=\u041f\u0456\u0434\u0433\u043e\u0442\u0443\u0432\u0430\u0442\u0438 \u043c\u0456\u0441\u0446\u0435 \u0456 \u0441\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u043d\u043e\u0432\u0438\u0439 \u0437\u0430\u043f\u043e\u0432\u043d\u0435\u043d\u0438\u0439 \u043d\u0443\u043b\u044f\u043c\u0438 \u0444\u0430\u0439\u043b
+ConfigView.label.zeronewfiles=\u041f\u0456\u0434\u0433\u043e\u0442\u0443\u0432\u0430\u0442\u0438 \u0440\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0456 \u0441\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u043d\u043e\u0432\u0438\u0439 \u0437\u0430\u043f\u043e\u0432\u043d\u0435\u043d\u0438\u0439 \u043d\u0443\u043b\u044f\u043c\u0438 \u0444\u0430\u0439\u043b
 ConfigView.label.zeronewfiles.tooltip=\u0417\u043c\u0435\u043d\u0448\u0443\u0454 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0456\u044e
 ConfigView.section.stats=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430
 ConfigView.section.stats.enable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438
@@ -485,15 +486,14 @@ ConfigView.section.stats.savefile=\u0406\u043c'\u044f \u0444\u0430\u0439\u043b\u
 ConfigView.section.stats.graph_update_dividers=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u0443 \u043b\u0456\u043d\u0456\u044e \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0436\u043d\u0456 60 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c
 MyTorrentsView.menu.export=&\u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 XML...
 MyTorrentsView.menu.host=&\u0425\u043e\u0441\u0442...
-ManagerItem.finishing=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f
+ManagerItem.finishing=\u0417\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f
 ConfigView.dialog.choosedefaulttorrentpath=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0442\u0435\u043a\u0443 \u0434\u043b\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
 ConfigView.dialog.choosemovepath=\u0412\u0438\u0431\u0435\u0440\u0435\u0442\u0435 \u0442\u0435\u043a\u0443 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0443
 ConfigView.label.movecompleted=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0444\u0430\u0439\u043b\u0438 (\u043f\u0456\u0441\u043b\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f)
-ConfigView.label.moveremoved=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0444\u0430\u0439\u043b\u0438 (\u043a\u043e\u043b\u0438 \u0456\u0441\u043d\u0443\u044e\u0447\u0456 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u0456)
-ConfigView.label.savetorrents=\u0417\u0431\u0435\u0440\u0456\u0433\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b\u0438
+ConfigView.label.moveremoved=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0444\u0430\u0439\u043b\u0438 (\u043a\u043e\u043b\u0438 \u043d\u0435 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u0456)
+ConfigView.label.savetorrents=\u0417\u0431\u0435\u0440\u0456\u0433\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
 MainWindow.menu.view.mytracker=\u041c\u043e\u0457 &\u0442\u0440\u0435\u043a\u0435\u0440\u0438
 MyTrackerView.title.full=\u041c\u043e\u0457 \u0442\u0440\u0435\u043a\u0435\u0440\u0438
-Tab.closeHint=(\u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c 'Esc' \u0434\u043b\u044f \u0437\u0430\u043a\u0440\u0438\u0442\u0442\u044f)
 MyTrackerView.name=\u041d\u0430\u0437\u0432\u0430
 MyTrackerView.tracker=\u0422\u0440\u0435\u043a\u0435\u0440
 MyTrackerView.status=\u0421\u0442\u0430\u0442\u0443\u0441
@@ -506,12 +506,12 @@ MyTrackerView.uploaded=\u0420\u043e\u0437\u0434\u0430\u043d\u0438\u0439
 MyTrackerView.downloaded=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0439
 MyTrackerView.left=\u0417\u0430\u043b\u0438\u0448\u0438\u043b\u043e\u0441\u044f
 ConfigView.section.style=\u0412\u0438\u0433\u043b\u044f\u0434
-ConfigView.label.set_ui_transfer_speeds=\u041a\u043e\u0440\u0435\u043a\u0442\u0443\u0432\u0430\u0442\u0438 \u043e\u0431\u0440\u0430\u043d\u0456 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0456
+ConfigView.label.set_ui_transfer_speeds=\u041f\u0456\u0434\u043c\u0456\u043d\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043d\u0456 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0456
 ConfigView.label.set_ui_transfer_speeds.description=\u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0438\u0431\u0440\u0430\u0442\u0438 \u0432\u0440\u0443\u0447\u043d\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0432 \u0440\u044f\u0434\u043a\u0443 \u0441\u0442\u0430\u0442\u0443\u0441\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u044e.\n\u0417\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043c\u0430\u044e\u0442\u044c \u0440\u043e\u0437\u0434\u0456\u043b\u044f\u0442\u0438\u0441\u044f \u043a\u043e\u043c\u043e\u044e.
 ConfigView.label.set_ui_transfer_speeds.description.download=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f (\u041a\u0431\u0456\u0442/c)
 ConfigView.label.set_ui_transfer_speeds.description.upload=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 (\u041a\u0431\u0456\u0442/c)
 ConfigView.section.style.useCustomTabs=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0438, \u044f\u043a\u0456 \u0437\u0430\u043a\u0440\u0438\u0432\u0430\u044e\u0442\u044c\u0441\u044f (\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443)
-MainWindow.menu.view.plugins=&\u0414\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f
+MainWindow.menu.view.plugins=\u0414\u043e&\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f
 fileDownloadWindow.saveTorrentIn=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u0432
 fileDownloadWindow.title=Vuze - \u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
 fileDownloadWindow.downloading=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0437 :
@@ -527,27 +527,27 @@ MyTorrentsView.menu.host.error.message=\u041f\u0440\u0438 \u0445\u043e\u0441\u04
 ConfigView.section.tracker=\u0422\u0440\u0435\u043a\u0435\u0440\u0438
 ConfigView.section.tracker.pollinterval=\u0406\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u0434\u043b\u044f \u043f\u0456\u0434\u0440\u0430\u0445\u0443\u043d\u043a\u0443 \u0433\u043e\u043b\u043e\u0441\u0456\u0432 (\u0441\u0435\u043a\u0443\u043d\u0434\u0438)
 ConfigView.section.tracker.publishenable=\u041f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u0442\u0438 \u0434\u0435\u0442\u0430\u043b\u0456 \u043f\u0440\u043e \u0442\u043e\u0440\u0435\u043d\u0442 \u043d\u0430 "<tracker_url>/"
-ConfigView.section.tracker.ip=IP \u0437\u043e\u0432\u043d\u0456\u0448\u043d\u044c\u043e\u0433\u043e \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+ConfigView.section.tracker.ip=\u0417\u043e\u0432\u043d\u0456\u0448\u043d\u0456\u0439 IP \u0442\u0440\u0435\u043a\u0435\u0440\u0430
 ConfigView.section.style.enableXPStyle=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0441\u0442\u0438\u043b\u044c XP (\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443)
 IPChecker.external.service.dyndns.name=\u0414\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u0438\u0439 DNS
-IPChecker.external.service.dyndns.description=\u0414\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u0456 DNS-\u0441\u0435\u0440\u0432\u0456\u0441\u0438 \u043c\u0435\u0440\u0435\u0436\u0456, LLC
-ConfigView.section.tracker.checkip=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u0438 \u0430\u0434\u0440\u0435\u0441\u0443...
+IPChecker.external.service.dyndns.description=\u0414\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u0456 \u0441\u0435\u0440\u0432\u0456\u0441\u0438 \u043c\u0435\u0440\u0435\u0436\u0456 DNS, LLC
+ConfigView.section.tracker.checkip=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0435 \u0432\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0437\u043e\u0432\u043d\u0456\u0448\u043d\u044c\u043e\u0457 \u0430\u0434\u0440\u0435\u0441\u0438...
 ipCheckerWizard.title=\u041c\u0430\u0439\u0441\u0442\u0435\u0440 "\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 IP"
 ipCheckerWizard.service=\u0421\u0435\u0440\u0432\u0456\u0441
 ipCheckerWizard.chooseService=\u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0441\u0435\u0440\u0432\u0456\u0441 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 IP \u0437 \u043d\u0438\u0436\u0447\u0435 \u0437\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0445
-ipCheckerWizard.explanations=\u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0446\u0435\u0439 \u043c\u0430\u0439\u0441\u0442\u0435\u0440 \u0434\u043b\u044f \u0432\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0432\u0430\u0448\u043e\u0457 \u0437\u043e\u0432\u043d\u0456\u0448\u043d\u044c\u043e\u0457 IP-\u0430\u0434\u0440\u0435\u0441\u0438. \u042f\u043a\u0449\u043e \u0432\u0430\u0448 IP \u0434\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u0438\u0439, \u043c\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u043c\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u0441\u0435\u0440\u0432\u0456\u0441 "\u0414\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u0456 DNS-\u0441\u0435\u0440\u0432\u0456\u0441\u0438 ". \u041d\u0438\u0436\u0447\u0435 \u0437\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0456 \u0434\u0435\u044f\u043a\u0456 \u0441\u043b\u0443\u0436\u0431\u0438, \u0449\u043e \u043f\u0440\u043e\u043f\u043e\u043d\u0443\u044e\u0442\u044c \u0446\u0435\u0439 \u0441\u0435\u0440\u0432\u0456\u0441, \u0430\u0434\u0440\u0435\u0441\u0438 \u044f\u043a\u0438\u0445 \u0432\u0435\u0434\u0443\u0442\u044c \u0434\u043e \u0440\u0435\u0454\u0441\u0442\u0440\u0430\u0446\u0456\u0457 (\u044f\u043a\u0449\u043e \u0432\u043e\u043d\u0430 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0430). \u041f\u043e\u0442\u0456\u043c \u0432\u043a\u0430\u0436\u0456\u0442\u044c \u0432 \u043f\u043e\u043b\u0456 IP-\u0430\u0434\u0440\u0435\u0441\u0438 \u0456\u043c'\u044f \u0432\u0430\u0448\u043e\u0433\u043e \u0445\u043e\u0441\u0442\u0443 (\u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434: myhostname.dyndns.org). \u0412\u0430\u043c \u0437\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432\u0430\u0448\u043e\u0433\u043e "\u0414\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u043e\u0433\u043e DNS-\u0441\u0435\u0440\u0432\u0456\u0441\u0443\u201d \u043d\u043e\u0432\u043e\u044e IP-\u0430\u0434\u0440\u0435\u0441\u043e\u044e. \u0423 \u0446\u044c\u043e\u043c\u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443 \u0412\u0438 \u0437\u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u043f\u043e\u043d\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u043d\u0430\u0432\u0456\u0442\u044c \u044f\u043a\u0449\u043e \u0432\u0430\u0448 IP \u0437\u043c\u0456\u043d\u044e\u0454\u0442\u044c\u0441\u044f.
+ipCheckerWizard.explanations=\u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0446\u0435\u0439 \u043c\u0430\u0439\u0441\u0442\u0435\u0440 \u0434\u043b\u044f \u0432\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0432\u0430\u0448\u043e\u0457 \u0437\u043e\u0432\u043d\u0456\u0448\u043d\u044c\u043e\u0457 IP-\u0430\u0434\u0440\u0435\u0441\u0438. \u042f\u043a\u0449\u043e \u0432\u0430\u0448 IP \u0434\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u0438\u0439, \u043c\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u043c\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u0441\u0435\u0440\u0432\u0456\u0441 "\u0414\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u0456 \u0441\u0435\u0440\u0432\u0456\u0441\u0438 DNS". \u041d\u0438\u0436\u0447\u0435 \u0437\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0456 \u0434\u0435\u044f\u043a\u0456 \u0441\u043b\u0443\u0436\u0431\u0438, \u0449\u043e \u043f\u0440\u043e\u043f\u043e\u043d\u0443\u044e\u0442\u044c \u0446\u0435\u0439 \u0441\u0435\u0440\u0432\u0456\u0441, \u0430\u0434\u0440\u0435\u0441\u0438 \u044f\u043a\u0438\u0445 \u0432\u0435\u0434\u0443\u0442\u044c \u0434\u043e \u0440\u0435\u0454\u0441\u0442\u0440\u0430\u0446\u0456\u0457 (\u044f\u043a\u0449\u043e \u0432\u043e\u043d\u0430 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0430). \u041f\u043e\u0442\u0456\u043c \u0432\u043a\u0430\u0436\u0456\u0442\u044c \u0432 \u043f\u043e\u043b\u0456 IP-\u0430\u0434\u0440\u0435\u0441\u0438 \u0456\u043c'\u044f \u0432\u0430\u0448\u043e\u0433\u043e \u0445\u043e\u0441\u0442\u0443 (\u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434: myhostname.dyndns.org). \u0412\u0430\u043c \u0437\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432\u0430\u0448\u043e\u0433\u043e "\u0414\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0456\u0441\u0443 DNS\u201d \u043d\u043e\u0432\u043e\u044e IP-\u0430\u0434\u0440\u0435\u0441\u043e\u044e. \u0423 \u0446\u044c\u043e\u043c\u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443 \u0412\u0438 \u0437\u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u043f\u043e\u043d\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u043d\u0430\u0432\u0456\u0442\u044c \u044f\u043a\u0449\u043e \u0432\u0430\u0448 IP \u0437\u043c\u0456\u043d\u044e\u0454\u0442\u044c\u0441\u044f.
 ipCheckerWizard.service.description=\u041e\u043f\u0438\u0441 :
-ipCheckerWizard.service.url=\u041b\u0456\u043d\u043a :
+ipCheckerWizard.service.url=\u041b\u0430\u043d\u043a\u0430:
 ipCheckerWizard.progresstitle=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 IP
 ipCheckerWizard.checkComplete=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0435\u043d\u0456 IP :
 ipCheckerWizard.checkFailed=\u041f\u043e\u043c\u0438\u043b\u043a\u0430! \u041f\u0440\u0438\u0447\u0438\u043d\u0430 :
 wizard.tracker.local=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u0442\u0440\u0435\u043a\u0435\u0440 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 Vuze
 wizard.tracker.external=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0437\u043e\u0432\u043d\u0456\u0448\u043d\u0456\u0439 \u0442\u0440\u0435\u043a\u0435\u0440
-wizard.tracker.howToLocal=\t\u0414\u043b\u044f \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c '\u0406\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438  > \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f > \u0422\u0440\u0435\u043a\u0435\u0440\u0438'
-wizard.announceUrl=URL \u0440\u043e\u0437\u0434\u0430\u0447\u0456 :
+wizard.tracker.howToLocal=\t\u0414\u043b\u044f \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c '\u0421\u0435\u0440\u0432\u0456\u0441  > \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f > \u0422\u0440\u0435\u043a\u0435\u0440\u0438'
+wizard.announceUrl=\u0410\u0434\u0440\u0435\u0441\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 :
 IPChecker.external.service.discoveryvip.name=\u0421\u0435\u0440\u0432\u0456\u0441 Discoveryvip
 IPChecker.external.service.discoveryvip.description=Discoveryvip - \u043b\u0438\u0448\u0435 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 IP-\u0430\u0434\u0440\u0435\u0441\u0438
-IPChecker.external.httpinvalidresponse=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u0432 HTTP-\u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u0456
+IPChecker.external.httpinvalidresponse=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u0432 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u0456 HTTP
 IPChecker.external.loadingwebpage=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0438 \u0406\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0443
 IPChecker.external.analysingresponse=\u0410\u043d\u0430\u043b\u0456\u0437 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u0456
 IPChecker.external.addressextracted=\u0414\u043e\u0431\u0443\u0442\u0456 \u0430\u0434\u0440\u0435\u0441\u0438 IP 
@@ -556,8 +556,8 @@ IPChecker.external.timeout=\u0427\u0430\u0441 \u043c\u0438\u043d\u0443\u0432
 IPChecker.external.ipnotfound=IP-\u0430\u0434\u0440\u0435\u0441\u0430 \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u0430
 ConfigView.section.tracker.pollintervalmin=\u041c\u0456\u043d\u0456\u043c\u0443\u043c
 ConfigView.section.tracker.pollintervalmax=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c
-ConfigView.section.tracker.pollintervalincby=\u041f\u0456\u0434\u0432\u0438\u0449\u0443\u0432\u0430\u0442\u0438 \u043f\u043e
-ConfigView.section.tracker.pollintervalincper=\u041a\u043e\u0436\u043d\u0438\u0445 N \u043a\u043b\u0456\u0454\u043d\u0442\u0456\u0432
+ConfigView.section.tracker.pollintervalincby=\u041f\u0456\u0434\u0432\u0438\u0449\u0443\u0432\u0430\u0442\u0438 \u043d\u0430
+ConfigView.section.tracker.pollintervalincper=\u041a\u043e\u0436\u043d\u0456 N \u043a\u043b\u0456\u0454\u043d\u0442\u0456\u0432
 splash.loadingImages=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c
 splash.initializeGui=\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0454\u0442\u044c\u0441\u044f \u0433\u043e\u043b\u043e\u0432\u043d\u0435 \u0432\u0456\u043a\u043d\u043e
 splash.openViews=\u0412\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u044e\u0442\u044c\u0441\u044f \u0432\u0438\u0433\u043b\u044f\u0434\u0438
@@ -570,9 +570,9 @@ MyTrackerView.completed=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u
 MainWindow.menu.file.open.torrentnodefault=\u0422\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b... (\u0431\u0435\u0437 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f)
 wizard.comment=\u041a\u043e\u043c\u0435\u043d\u0442\u0430\u0440
 ConfigView.label.movetorrent=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442
-ConfigView.label.movepartialdownloads=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438, \u043a\u043e\u043b\u0438 \u0434\u0435\u044f\u043a\u0456 \u0444\u0430\u0439\u043b\u0438 \u0432\u0456\u0434\u0437\u043d\u0430\u0447\u0435\u043d\u0456 "\u041d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438" 
+ConfigView.label.movepartialdownloads=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438, \u043d\u0430\u0432\u0456\u0442\u044c \u043a\u043e\u043b\u0438 \u0434\u0435\u044f\u043a\u0456 \u0444\u0430\u0439\u043b\u0438 \u0432\u0456\u0434\u0437\u043d\u0430\u0447\u0435\u043d\u0456 "\u041d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438" 
 ConfigView.label.subdir_is_in_default=\u0412\u0440\u0430\u0445\u043e\u0432\u0443\u0432\u0430\u0442\u0438, \u0449\u043e \u044f\u043a\u0449\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0456\u0441\u043d\u0443\u044e\u0442\u044c \u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0456\u0439 \u0442\u0435\u0446\u0456, \u0442\u043e \u0446\u0435 \u0441\u0442\u043e\u0441\u0443\u0454\u0442\u044c\u0441\u044f \u0456 \u043f\u0456\u0434\u0442\u0435\u043a
-ConfigView.section.file.decoder.label=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0435 \u043a\u043e\u0434\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443,\n \u044f\u043a\u0449\u043e \u043f\u043e\u0442\u0440\u0456\u0431\u0435\u043d \u0432\u0438\u0431\u0456\u0440 
+ConfigView.section.file.decoder.label=C\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0435 \u043a\u043e\u0434\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443,\n \u044f\u043a\u0449\u043e \u043f\u043e\u0442\u0440\u0456\u0431\u0435\u043d \u0432\u0438\u0431\u0456\u0440 
 ConfigView.section.file.decoder.nodecoder=\u041d\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442.
 IPChecker.external.service.no-ip.name=\u041d\u0435 IP
 IPChecker.external.service.no-ip.description=\u0421\u043b\u0443\u0436\u0431\u0438 \u0441\u0435\u0440\u0432\u0456\u0441\u0456\u0432 \u0434\u0438\u043d\u0430\u043c\u0456\u0447\u043d\u0438\u0445 \u0456 \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u0438\u0445 DNS\n (\u0431\u0435\u0437 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0456\u0441\u0443 '\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0406\u0420')
@@ -582,7 +582,7 @@ ConfigView.label.playdownloadspeech.info=\u0421\u0438\u043d\u0442\u0435\u0437\u0
 #
 # Tooltips
 #
-GeneralView.label.status.pieces_available.tooltip=\u041f\u043e\u043a\u0430\u0437\u0443\u0454 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0445 \u043a\u043e\u043f\u0456\u0439 \u043a\u043e\u0436\u043d\u043e\u0457 \u0447\u0430\u0441\u0442\u0438\u043d\u0438.\n\u042f\u043a\u0449\u043e \u0437\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043c\u0435\u043d\u0448\u0435 1, \u0442\u043e\u0434\u0456 \u0432\u0435\u0441\u044c \u0444\u0430\u0439\u043b \u043d\u0430 \u0434\u0430\u043d\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439, \u0446\u0435 \u043c\u043e\u0436\u0435 \u0437\u0440\u043e\u0431\u0438\u0442\u0438 \u043d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u0438\u043c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.
+GeneralView.label.status.pieces_available.tooltip=\u041f\u043e\u043a\u0430\u0437\u0443\u0454 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0445 \u043a\u043e\u043f\u0456\u0439 \u043a\u043e\u0436\u043d\u043e\u0457 \u0447\u0430\u0441\u0442\u0438\u043d\u0438.\n\u042f\u043a\u0449\u043e \u0437\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043c\u0435\u043d\u0448\u0435 1, \u0442\u043e\u0434\u0456 \u0432\u0435\u0441\u044c \u0444\u0430\u0439\u043b \u043d\u0430 \u0434\u0430\u043d\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439, \u0446\u0435 \u043c\u043e\u0436\u0435 \u0437\u0440\u043e\u0431\u0438\u0442\u0438 \u043d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u0438\u043c \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.
 GeneralView.label.trackerurl.tooltip=\u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u0437\u0430\u043f\u0430\u043c'\u044f\u0442\u0430\u0442\u0438 \u0430\u0434\u0440\u0435\u0441\u0443 \u0430\u043d\u043e\u043d\u0441\u0430
 GeneralView.label.trackerurlopen.tooltip=\u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443 \u0442\u0440\u0435\u043a\u0435\u0440\u0443
 #
@@ -593,9 +593,9 @@ ConfigView.section.style.inactiveUpdate=\u041f\u043e\u043d\u043e\u0432\u043b\u04
 ConfigView.section.style.graphicsUpdate=\u041f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0433\u0440\u0430\u0444\u0456\u0447\u043d\u0438\u0445 \u043b\u043e\u0433\u0456\u0432 \u043a\u043e\u0436\u043d\u0456 N \u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c \u0433\u0440\u0430\u0444\u0456\u0447\u043d\u043e\u0433\u043e \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u043d\u044f
 ConfigView.section.style.reOrderDelay=\u041f\u0435\u0440\u0435\u0433\u0440\u0443\u043f\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044c \u043a\u043e\u0436\u043d\u0456 N \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c \u0433\u0440\u0430\u0444\u0456\u0447\u043d\u043e\u0433\u043e \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u043d\u044f [0: \u043d\u0456\u043a\u043e\u043b\u0438]
 ConfigView.section.style.reOrderDelay.never=\u041d\u0456\u043a\u043e\u043b\u0438
-ConfigView.section.logging=\u041b\u043e\u0433 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457
-ConfigView.section.logging.enable=\u0417\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u0442\u0438 \u043b\u043e\u0433 \u0432 \u0444\u0430\u0439\u043b
-ConfigView.section.logging.logdir=\u0417\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 \u043b\u043e\u0433\u0443 \u0432 \u0442\u0435\u043a\u0443
+ConfigView.section.logging=\u0417\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0432 \u0444\u0430\u0439\u043b .log
+ConfigView.section.logging.enable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0432 \u0444\u0430\u0439\u043b .log
+ConfigView.section.logging.logdir=\u0417\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 .log \u0432 \u0442\u0435\u043a\u0443
 ConfigView.section.logging.choosedefaultsavepath=\u0412\u0438\u0431\u0456\u0440 \u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
 GeneralView.label.updatein.querying=\u0417'\u0454\u0434\u043d\u0443\u044e\u0441\u044f...
 configureWizard.nat.sharePort=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043e\u0434\u0438\u043d \u0432\u0445\u0456\u0434\u043d\u0438\u0439 \u043f\u043e\u0440\u0442 \u0434\u043b\u044f \u0432\u0441\u0456\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
@@ -613,39 +613,39 @@ TableColumn.header.shareRatio=\u0421\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u
 MyTorrentsView.menu.editTableColumns=&\u0412\u0438\u0431\u0456\u0440 \u0441\u0442\u043e\u0432\u043f\u0446\u0456\u0432
 wizard.operationfailed=\u041e\u043f\u0435\u0440\u0430\u0446\u0456\u044f \u043d\u0435 \u043f\u0440\u043e\u0439\u0448\u043b\u0430 \u0443\u0441\u043f\u0456\u0448\u043d\u043e
 authenticator.title=\u041f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u0432\u043a\u0430\u0437\u0430\u0442\u0438 \u043f\u0430\u0440\u043e\u043b\u044c
-authenticator.realm=\u041e\u0431\u043b\u0430\u0441\u0442\u044c
+authenticator.realm=\u0414\u0456\u043b\u044f\u043d\u043a\u0430
 authenticator.tracker=\u0422\u0440\u0435\u043a\u0435\u0440
 authenticator.user=\u0406\u043c'\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430
 authenticator.password=\u041f\u0430\u0440\u043e\u043b\u044c
 ConfigView.label.allowSendVersion=\u0414\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u0438 Vuze \u0430\u043d\u043e\u043d\u0456\u043c\u043d\u0435 \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f \u043d\u043e\u043c\u0435\u0440\u0430 \u0432\u0435\u0440\u0441\u0456\u0457 \u0456 \u0432\u0438\u0431\u0456\u0440\u043a\u043e\u0432\u043e\u0457 \u0456\u0434\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u0457 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 \u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438.
 ConfigView.label.version.info.link=\u0412\u0456\u0434\u0432\u0456\u0434\u0430\u0439\u0442\u0435 \u0434\u043b\u044f \u0431\u0456\u043b\u044c\u0448 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u043f\u0440\u043e \u0442\u0435,  \u044f\u043a\u0456 \u0434\u0430\u043d\u0456 \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0456 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 \u0432\u0435\u0440\u0441\u0456\u0457
-wizard.hint.mode=\u041f\u043e\u0440\u0430\u0434\u0430:\t\u041c\u043e\u0436\u043d\u0430 \u043f\u0435\u0440\u0435\u0442\u044f\u0433\u043d\u0443\u0442\u0438 \u0443 \u0432\u0456\u043a\u043d\u043e \u043c\u0430\u0439\u0441\u0442\u0440\u0430\n\t\u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0456 \u0444\u0430\u0439\u043b \u0430\u0431\u043e \u0442\u0435\u043a\u0443
+wizard.hint.mode=\u041f\u043e\u0440\u0430\u0434\u0430:\t\u041c\u043e\u0436\u043d\u0430 \u043f\u0435\u0440\u0435\u0442\u044f\u0433\u043d\u0443\u0442\u0438 \u0443 \u0432\u0456\u043a\u043d\u043e \u043c\u0430\u0439\u0441\u0442hf\n\t\u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0456 \u0444\u0430\u0439\u043b \u0430\u0431\u043e \u0442\u0435\u043a\u0443
 wizard.hint.file=\u041f\u043e\u0440\u0430\u0434\u0430:\t\u041c\u043e\u0436\u043b\u0438\u0432\u0438\u0439 \u0432\u0438\u0431\u0456\u0440 \u0444\u0430\u0439\u043b\u0443 \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443
 wizard.hint.directory=\u041f\u043e\u0440\u0430\u0434\u0430:\t\u041c\u043e\u0436\u043b\u0438\u0432\u0438\u0439 \u0432\u0438\u0431\u0456\u0440 \u0442\u0435\u043a\u0438 \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u043f\u0435\u0440\u0435\u0442\u044f\u0433\u0443\u0432\u0430\u043d\u043d\u044f
 MainWindow.menu.help.checkupdate=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u0438 \u043f\u043e&\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
 TableColumn.header.down=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456
 TableColumn.header.up=\u0420\u043e\u0437\u0434\u0430\u043d\u0456
-ConfigView.section.tracker.passwordenabletorrent.info=\u041f\u043e\u0442\u0440\u0456\u0431\u0435\u043d BitTorrent-\u043a\u043b\u0456\u0454\u043d\u0442 (\u043d\u0430\u043f\u0440.: Vuze)
+ConfigView.section.tracker.passwordenabletorrent.info=\u041f\u043e\u0442\u0440\u0456\u0431\u043d\u0438\u0439 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u043d\u0438\u0439 BitTorrent-\u043a\u043b\u0456\u0454\u043d\u0442 (\u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434: Vuze)
 ConfigView.section.style.confirmationOnExit=\u0417\u0430\u043f\u0438\u0442\u0443\u0432\u0430\u0442\u0438 \u043f\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0436\u0435\u043d\u043d\u044f, \u043a\u043e\u043b\u0438 \u0412\u0438 \u0432\u0438\u0445\u043e\u0434\u0438\u0442\u0435
 MainWindow.dialog.exitconfirmation.title=\u0412\u0438\u0439\u0442\u0438 \u0437 Vuze
-MainWindow.dialog.exitconfirmation.text=\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u043f\u043e\u043a\u0438\u043d\u0443\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0443?
+MainWindow.dialog.exitconfirmation.text=\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u043f\u043e\u043a\u0438\u043d\u0443\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0443
 SystemTray.menu.stopalltransfers=\u0417\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u0432\u0441\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 TrayWindow.menu.stopalldownloads=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u0432\u0441&\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 ConfigView.section.tracker.sslport.info=\u0414\u0438\u0432. FAQ \u0434\u043b\u044f \u043f\u043e\u0434\u0430\u043b\u044c\u0448\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457
 wizard.tracker.ssl=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 SSL
 ConfigView.label.playdownloadfinished=\u041f\u0456\u0441\u043b\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u043c\u0443\u0437. \u0444\u0430\u0439\u043b
-ConfigView.label.popupdownloadfinished=\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u043f\u0440\u043e \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
-ConfigView.label.popupfilefinished=\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u043f\u0440\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0439 \u0444\u0430\u0439\u043b
+ConfigView.label.popupdownloadfinished=\u0412\u0438\u0440\u0438\u043d\u0430\u044e\u0447\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u043f\u0440\u043e \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
+ConfigView.label.popupfilefinished=\u0412\u0438\u0440\u0438\u043d\u0430\u044e\u0447\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u043f\u0440\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0439 \u0444\u0430\u0439\u043b
 TableColumn.header.pieces=\u0427\u0430\u0441\u0442\u0438\u043d
 TableColumn.header.pieces.info=\u0413\u0440\u0430\u0444\u0456\u0447\u043d\u0438\u0439 \u043f\u043e\u043a\u0430\u0437\u043d\u0438\u043a \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0445 \u0447\u0430\u0441\u0442\u0438\u043d
-TableColumn.header.completion=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f
-TableColumn.header.completion.info=\u0421\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0432 %
-ConfigView.section.style.showdownloadbasket=\u0410\u043a\u0442\u0438\u0432\u0443\u0432\u0430\u0442\u0438 "\u043a\u043e\u0448\u0438\u043a \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c" (\u0443 \u044f\u043a\u0438\u0439 \u043c\u043e\u0436\u043d\u0430 \u0437\u0430\u043a\u0438\u0434\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432)
+TableColumn.header.completion=\u0417\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f
+TableColumn.header.completion.info=\u0421\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0432 %
+ConfigView.section.style.showdownloadbasket=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 "\u043a\u043e\u0448\u0438\u043a \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c" (\u0443 \u044f\u043a\u0438\u0439 \u043c\u043e\u0436\u043d\u0430 \u0437\u0430\u043a\u0438\u0434\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432)
 ConfigView.section.style.alwaysShowTorrentFiles=\u0417\u0430\u0432\u0436\u0434\u0438 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0434\u043e\u043a\u043b\u0430\u0434\u043d\u0443 (\u0444\u0430\u0439\u043b\u043e\u0432\u0443) \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u043f\u0440\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0438
 wizard.multitracker=\u0414\u043e\u0434\u0430\u0442\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0437 \u043c\u0443\u043b\u044c\u0442\u0438-\u0442\u0440\u0435\u043a\u0435\u0440\u0443
 wizard.multitracker.title=\u041c\u0443\u043b\u044c\u0442\u0438-\u0442\u0440\u0435\u043a\u0435\u0440
 wizard.multitracker.configuration=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043c\u0443\u043b\u044c\u0442\u0438-\u0442\u0440\u0435\u043a\u0435\u0440\u0430
-wizard.multitracker.new=\u041d\u043e\u0432\u0438\u0439 ...
+wizard.multitracker.new=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438...
 wizard.multitracker.edit=\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438...
 wizard.multitracker.delete=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438
 wizard.multitracker.group=\u0413\u0440\u0443\u043f\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0456\u0432
@@ -654,18 +654,18 @@ wizard.multitracker.edit.name=\u041d\u0430\u0437\u0432\u0430
 wizard.multitracker.edit.save=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438
 wizard.multitracker.edit.newgroup=\u041d\u043e\u0432\u0430 \u0433\u0440\u0443\u043f\u0430
 wizard.multitracker.edit.deletegroup=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438
-wizard.multitracker.edit.newtracker=\u041d\u043e\u0432\u0438\u0439 \u0442\u0440\u0435\u043a\u0435\u0440
+wizard.multitracker.edit.newtracker=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0442\u0440\u0435\u043a\u0435\u0440
 wizard.multitracker.edit.deletetracker=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438
 wizard.multitracker.edit.edit=\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438
-wizard.addingmt=\u0414\u043e\u0431\u0430\u0432\u043a\u0430 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0437 \u043c\u0443\u043b\u044c\u0442\u0438-\u0442\u0440\u0435\u043a\u0435\u0440\u0443
-wizard.multitracker.noannounce=URL-\u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043d\u0435 \u0456\u0441\u043d\u0443\u0454 \u0432 \u0441\u043f\u0438\u0441\u043a\u0443 \u0442\u0440\u0435\u043a\u0435\u0440\u0456\u0432
-MyTorrentsView.menu.recheck=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0432\u0440\u0443\u0447\u043d\u0443
+wizard.addingmt=\u0414\u043e\u0434\u0430\u0432\u0430\u043d\u043d\u044f \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0437 \u043c\u0443\u043b\u044c\u0442\u0438-\u0442\u0440\u0435\u043a\u0435\u0440\u0443
+wizard.multitracker.noannounce=\u0410\u0434\u0440\u0435\u0441\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043d\u0435 \u0456\u0441\u043d\u0443\u0454 \u0432 \u0441\u043f\u0438\u0441\u043a\u0443 \u0442\u0440\u0435\u043a\u0435\u0440\u0456\u0432
+MyTorrentsView.menu.recheck=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u0438 \u043f\u0440\u0438&\u0441\u043a\u043e\u0440\u0435\u043d\u043e
 iconBar.showDownloadBar.tooltip=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
-iconBar.start.tooltip=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438
-iconBar.stop.tooltip=\u0417\u0443\u043f\u0438\u043d\u0438\u0442\u0438
+iconBar.start.tooltip=\u041f\u043e\u0447\u0430\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043d\u0438\u0439(\u0456) \u0442\u043e\u0440\u0435\u043d\u0442(\u0438)
+iconBar.stop.tooltip=\u0417\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043d\u0438\u0439(\u0456) \u0442\u043e\u0440\u0435\u043d\u0442(\u0438)
 iconBar.remove.tooltip=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438
 iconBar.openNoDefault.tooltip=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b (\u0431\u0435\u0437 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f)
-iconBar.openURL.tooltip=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 URL-\u0430\u0434\u0440\u0435\u0441\u0443
+iconBar.openURL.tooltip=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0430\u0434\u0440\u0435\u0441\u0443
 iconBar.openFolder.tooltip=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u0435\u043a\u0443
 iconBar.new.tooltip=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442
 iconBar.up.tooltip=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0434\u043e\u0433\u043e\u0440\u0438
@@ -674,29 +674,29 @@ iconBar.run.tooltip=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438
 iconBar.host.tooltip=\u0425\u043e\u0441\u0442
 iconBar.publish.tooltip=\u041e\u043f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u0442\u0438
 iconBar.editcolumns.tooltip=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0441\u0442\u043e\u0432\u043f\u0446\u044f
-MyTorrentsView.menu.editTracker=&\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438 URL(\u0438) \u0442\u0440\u0435\u043a\u0435\u0440\u0443
+MyTorrentsView.menu.editTracker=&\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438 \u0430\u0434\u0440\u0435\u0441\u0443(\u0438) \u0442\u0440\u0435\u043a\u0435\u0440\u0443
 GeneralView.menu.selectTracker=\u0412\u0438\u0431\u0440\u0430\u0442\u0438
 ConfigView.section.stats.xslfile=\u0406\u043c'\u044f XSL-\u0444\u0430\u0439\u043b\u0443
 ConfigView.section.stats.xslfiledetails=\u0414\u043e\u0434\u0430\u0454\u0442\u044c\u0441\u044f \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0444\u0430\u0439\u043b\u0443 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0437 \u0442\u0435\u0433\u043e\u043c <?xml-stylesheet>
 ConfigView.label.savetorrentbackup=\u0417\u0431\u0435\u0440\u0456\u0433\u0430\u0442\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0443 \u043a\u043e\u043f\u0456\u044e
 ConfigView.section.tracker.forceport=\u041f\u0440\u0438\u043c\u0443\u0441\u043e\u0432\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0443 \u0434\u043b\u044f \u0437\u043e\u0432\u043d\u0456\u0448\u043d\u0456\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
-ConfigView.section.ipfilter.allow=\u0414\u041e\u0417\u0412\u041e\u041b\u0418\u0422\u0418 \u0446\u0456 \u0434\u0456\u0430\u043f\u0430\u0437\u043e\u043d\u0438 (\u0437\u0430\u0437\u0432\u0438\u0447\u0430\u0439 \u0417\u0410\u0411\u041e\u0420\u041e\u041d\u0415\u041d\u0406)
+ConfigView.section.ipfilter.allow=\u0414\u041e\u0417\u0412\u041e\u041b\u0418\u0422\u0418 \u0446\u0456 \u0434\u0456\u0430\u043f\u0430\u0437\u043e\u043d\u0438 (\u0437\u0432\u0438\u0447\u0430\u0439\u043d\u043e \u0417\u0410\u0411\u041e\u0420\u041e\u041d\u0415\u041d\u0406)
 ConfigView.section.ipfilter.list.inrange=\u0431\u0443\u0432 \u0443 \u0441\u043f\u0438\u0441\u043a\u0443
 ConfigView.section.ipfilter.list.notinrange=\u043d\u0435 \u0431\u0443\u0432 \u0443 \u0436\u043e\u0434\u043d\u043e\u043c\u0443 \u0441\u043f\u0438\u0441\u043a\u0443
 ConfigView.section.ipfilter.list.title=\u0421\u043f\u0438\u0441\u043e\u043a \u0431\u043b\u043e\u043a\u043e\u0432\u0430\u043d\u0438\u0445 IP
 ConfigView.label.allowsameip=\u0414\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u0438 \u0431\u0456\u043b\u044c\u0448\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0437\u0432'\u044f\u0437\u043a\u0443 \u0437 \u043e\u0434\u043d\u0456\u0454\u0457 \u0456 \u0442\u0456\u0454\u0457 \u0436 IP
-ConfigView.label.allowsameip.tooltip=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443 \u043f\u043e\u0442\u0440\u0435\u0431\u0438.\n\u041f\u0440\u0438 \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u0456 \u0454 \u0437\u0430\u0445\u0438\u0441\u0442\u043e\u043c \u0432\u0456\u0434 \u043b\u0456\u0447\u0435\u0440\u0456\u0432
+ConfigView.label.allowsameip.tooltip=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443 \u043f\u043e\u0442\u0440\u0435\u0431\u0438.\n\u0412 \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u043e\u043c\u0443 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u0456 \u0454 \u0437\u0430\u0445\u0438\u0441\u0442\u043e\u043c \u0432\u0456\u0434 \u043b\u0456\u0447\u0435\u0440\u0456\u0432
 ManagerItem.superseeding=\u0421\u0443\u043f\u0435\u0440-\u0440\u043e\u0437\u0434\u0430\u0447\u0430
 ConfigView.label.userSuperSeeding=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0441\u0443\u043f\u0435\u0440-\u0440\u043e\u0437\u0434\u0430\u0447\u0443
 PeersView.uniquepiece=\u0427\u0430\u0441\u0442\u0438\u043d\u0430 (\u0440\u0435\u0436\u0438\u043c \u0441\u0443\u043f\u0435\u0440-\u0440\u043e\u0437\u0434\u0430\u0447\u0456)
-PeersView.uniquepiece.none=\u041d\u0435\u043c\u0430\u0454
+PeersView.uniquepiece.none=\u041d\u0435\u043c\u0430
 PeersView.timetosend=\u041f\u0440\u0438\u0439\u0448\u043e\u0432 \u0447\u0430\u0441 \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u0438\u0442\u0438 \u0447\u0430\u0441\u0442\u0438\u043d\u0443 \u0437\u0430\u043d\u043e\u0432\u043e (\u0420\u0435\u0436\u0438\u043c \u0441\u0443\u043f\u0435\u0440-\u0440\u043e\u0437\u0434\u0430\u0447\u0456)
-ConfigView.section.style.addurlsilently=\u0412\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0442\u0438 URL \u0431\u0435\u0437 \u0434\u0456\u0430\u043b\u043e\u0433\u0443
-ConfigView.section.style.addurlsilently.tooltip=\u0423\u0432\u0430\u0433\u0430: \u044f\u043a\u0449\u043e \u043e\u043f\u0446\u0456\u044f \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0430, \u0433\u043e\u043b\u043e\u0432\u043d\u0435 \u0432\u0456\u043a\u043d\u043e \u043d\u0435 \u0431\u0443\u0434\u0435 \u0437\u043d\u043e\u0432\u0443 \u0432\u0438\u0434\u0438\u043c\u0438\u043c!\n\u041f\u0440\u0438 \u0432\u0442\u0440\u0430\u0442\u0456 \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0438 \u0442\u0440\u0435\u044e \u0432\u0438\u043c\u043a\u043d\u0456\u0442\u044c \u0446\u044e \u043e\u043f\u0446\u0456\u044e.
-ConfigView.section.file.decoder.prompt=\u041f\u0440\u0438 \u043c\u043e\u0436\u043b\u0438\u0432\u043e\u0441\u0442\u0456 \u0432\u0438\u0431\u043e\u0440\u0443 \u0437\u0430\u0432\u0436\u0434\u0438 \u0437\u0430\u043f\u0438\u0442\u0443\u0432\u0430\u0442\u0438
-ConfigView.section.file.decoder.prompt.tooltip=\u041f\u0440\u0438 \u043c\u043e\u0436\u043b\u0438\u0432\u043e\u0441\u0442\u0456 \u0432\u0438\u0431\u043e\u0440\u0443 \u0437\u0430\u0432\u0436\u0434\u0438 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0434\u0456\u0430\u043b\u043e\u0433
-MyTorrentsView.menu.moveTop=\u0412 \u0441\u0430&\u043c\u0438\u0439 \u0432\u0435\u0440\u0445
-MyTorrentsView.menu.moveEnd=\u0412 &\u0441\u0430\u043c\u0438\u0439 \u043d\u0438\u0437
+ConfigView.section.style.addurlsilently=\u0412\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0442\u0438 \u0430\u0434\u0440\u0435\u0441\u0438 \u0431\u0435\u0437 \u0434\u0456\u0430\u043b\u043e\u0433\u0443
+ConfigView.section.style.addurlsilently.tooltip=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u0438\u0439\u043d\u044f\u0442\u0456 \u0430\u0431\u043e \u0432\u0456\u0434\u0445\u0438\u043b\u0435\u043d\u0456 \u0444\u0430\u0439\u043b\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437 \u0430\u0434\u0440\u0435\u0441 \u0431\u0435\u0437 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0442\u044f \u0432\u0456\u043a\u043d\u0430 \u0437\u0430\u043f\u0438\u0442\u0443.
+ConfigView.section.file.decoder.prompt=\u0417\u0430 \u0437\u043c\u043e\u0433\u0438 \u0432\u0438\u0431\u043e\u0440\u0443 \u0437\u0430\u0432\u0436\u0434\u0438 \u0437\u0430\u043f\u0438\u0442\u0443\u0432\u0430\u0442\u0438
+ConfigView.section.file.decoder.prompt.tooltip=\u0417\u0430 \u0437\u043c\u043e\u0433\u0438 \u0432\u0438\u0431\u043e\u0440\u0443 \u0437\u0430\u0432\u0436\u0434\u0438 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0434\u0456\u0430\u043b\u043e\u0433
+MyTorrentsView.menu.moveTop=\u0414\u043e \u0441\u0430&\u043c\u043e\u0433\u043e \u0432\u0435\u0440\u0445\u0443
+MyTorrentsView.menu.moveEnd=\u0414\u043e &\u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0438\u0437\u0443
 ConfigView.label.moveonlyusingdefaultsave=\u041b\u0438\u0448\u0435 \u044f\u043a\u0449\u043e \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0456\u0439 \u0442\u0435\u0446\u0456
 ConfigView.label.moveonlyusingdefaultsave.tooltip=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443, \u044f\u043a\u0449\u043e \u0442\u043e\u0440\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0431\u0443\u0432\u0430\u0454 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0456\u0439 \u043f\u0430\u043f\u0446\u0456
 ConfigView.label.watchtorrentfolder=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0438\u0439 \u0456\u043c\u043f\u043e\u0440\u0442 \u043d\u043e\u0432\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
@@ -715,15 +715,15 @@ MainWindow.menu.view.stats=&\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u04
 SpeedView.title.full=\u0410\u043a\u0442\u0438\u0432\u043d\u0456\u0441\u0442\u044c 
 SpeedView.downloadSpeed.title=\u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 SpeedView.uploadSpeed.title=\u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456
-ConfigView.section.style.useSIUnits=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043e\u0434\u0438\u043d\u0438\u0446\u0456 \u0421\u0406 (KB -> Ki\u0412 \u0456 \u0456\u043d.)
-iconBar.top.tooltip=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u043d\u0430 \u0441\u0430\u043c\u0438\u0439 \u0432\u0435\u0440\u0445
-iconBar.bottom.tooltip=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u043d\u0430 \u0441\u0430\u043c\u0438\u0439 \u043d\u0438\u0437
+ConfigView.section.style.useSIUnits=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043e\u0434\u0438\u043d\u0438\u0446\u0456 IEC (K\u0431\u0430\u0439\u0442 -> Ki\u0411 \u0456 \u0456\u043d.)
+iconBar.top.tooltip=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0434\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u0432\u0435\u0440\u0445\u0443
+iconBar.bottom.tooltip=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0434\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u043d\u0438\u0437\u0443
 TableColumn.header.health=\u0421\u0442\u0430\u043d
 MyTorrentsView.menu.health=\u0420\u043e\u0437\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c
 health.explain.grey=\u043e\u0437\u043d\u0430\u0447\u0430\u0454 \u0442\u0435, \u0449\u043e \u0442\u043e\u0440\u0435\u043d\u0442 \u043d\u0435 \u043f\u0440\u0430\u0446\u044e\u0454 (\u043d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0454\u0442\u044c\u0441\u044f \u0430\u0431\u043e \u043d\u0435 \u0440\u043e\u0437\u0434\u0430\u0454\u0442\u044c\u0441\u044f)
 health.explain.red=\u043e\u0437\u043d\u0430\u0447\u0430\u0454, \u0449\u043e \u0412\u0438 \u043d\u0435 \u0437'\u0454\u0434\u043d\u0430\u043d\u0456 \u0437 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c\u0438 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 health.explain.blue=\u043f\u0440\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043e\u0437\u043d\u0430\u0447\u0430\u0454, \u0449\u043e \u0412\u0438 \u043d\u0435 \u0437'\u0454\u0434\u043d\u0430\u043d\u0456 \u0437 \u0436\u043e\u0434\u043d\u0438\u043c \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u043e\u043c\n\u043f\u0440\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u0456 - \u0449\u043e \u0412\u0438 \u0437'\u0454\u0434\u043d\u0430\u043d\u0456 \u0437 \u0434\u0435\u043a\u0438\u043c \u0437 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432, \u0430\u043b\u0435 \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0435 \u043f\u0440\u0430\u0446\u044e\u0454
-health.explain.yellow=\u043e\u0437\u043d\u0430\u0447\u0430\u0454 \u043f\u0440\u043e \u0442\u0435, \u0449\u043e \u0442\u0440\u0435\u043a\u0435\u0440 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0443, \u0412\u0438 \u0437'\u0454\u0434\u043d\u0430\u043d\u0456 \u0437 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c\u0438, \u0430\u043b\u0435 \u0437\u0432'\u044f\u0437\u043a\u0443 \u043a\u0435\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0435\u043c\u0430\u0454.\n\u0419\u043c\u043e\u0432\u0456\u0440\u043d\u043e, \u0432 \u0432\u0430\u0441 NAT-\u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u044f\u043a\u0449\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0432\u0432\u0435\u0441\u044c \u0447\u0430\u0441 \u0436\u043e\u0432\u0442\u0456
+health.explain.yellow=\u043e\u0437\u043d\u0430\u0447\u0430\u0454 \u043f\u0440\u043e \u0442\u0435, \u0449\u043e \u0442\u0440\u0435\u043a\u0435\u0440 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0443, \u0412\u0438 \u0437'\u0454\u0434\u043d\u0430\u043d\u0456 \u0437 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c\u0438, \u0430\u043b\u0435 \u0437\u0432'\u044f\u0437\u043a\u0443 \u043a\u0435\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0435\u043c\u0430.\n\u0419\u043c\u043e\u0432\u0456\u0440\u043d\u043e, \u0432 \u0432\u0430\u0441 NAT-\u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u044f\u043a\u0449\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0432\u0432\u0435\u0441\u044c \u0447\u0430\u0441 \u0436\u043e\u0432\u0442\u0456
 health.explain.green=\u043e\u0437\u043d\u0430\u0447\u0430\u0454, \u0449\u043e \u0432\u0441\u0435 \u0433\u0430\u0440\u0430\u0437\u0434
 ConfigView.section.style.alwaysRefreshMyTorrents=\u0417\u0430\u0432\u0436\u0434\u0438 \u043f\u043e\u043d\u043e\u0432\u043b\u044e\u0432\u0430\u0442\u0438 "\u041c\u043e\u0457 \u0442\u043e\u0440\u0435\u043d\u0442\u0438"
 ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=\u0426\u044f \u0444\u0443\u043d\u043a\u0446\u0456\u044f \u043f\u043e\u043d\u043e\u0432\u043b\u044e\u0454 \u043f\u043e\u043a\u0430\u0437\u043d\u0438\u043a "\u041c\u043e\u0457 \u0442\u043e\u0440\u0435\u043d\u0442\u0438", \u043d\u0430\u0432\u0456\u0442\u044c \u044f\u043a\u0449\u043e \u0432\u0456\u043d \u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u0439 (\u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0434\u0435\u044f\u043a\u0456 mIRC-\u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f\u043c\u0438)
@@ -742,19 +742,19 @@ security.certtruster.no=\u041d\u0456
 ConfigView.section.tracker.torrentsperpage=\u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u043d\u0430 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
 MainWindow.menu.file.share=&\u0420\u043e\u0437\u0434\u0430\u0442\u0438
 MainWindow.menu.file.share.file=&\u0424\u0430\u0439\u043b...
-MainWindow.menu.file.share.dir=&\u041f\u0430\u043f\u043a\u0443...
+MainWindow.menu.file.share.dir=&\u0422\u0435\u043a\u0443...
 MainWindow.menu.file.share.dircontents=&\u0412\u043c\u0456\u0441\u0442 \u0442\u0435\u043a\u0438
 MainWindow.menu.file.share.dircontentsrecursive=\u0412&\u043c\u0456\u0441\u0442 \u0442\u0435\u043a\u0438 \u0456 \u0432\u0441\u0456\u0445 \u0457\u0457 \u043f\u0456\u0434\u0442\u0435\u043a...
 MainWindow.dialog.share.sharefile=\u0412\u0438\u0431\u0456\u0440 \u0444\u0430\u0439\u043b\u0443 \u0434\u043b\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 MainWindow.dialog.share.sharedir=\u0412\u0438\u0431\u0456\u0440 \u0442\u0435\u043a\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 MainWindow.dialog.share.sharedircontents=\u0412\u0438\u0431\u0456\u0440 \u0432\u043c\u0456\u0441\u0442\u0443 \u0442\u0435\u043a\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
-MainWindow.dialog.share.sharedircontents.recursive=\u0406 \u0432\u043c\u0456\u0441\u0442 \u0432\u0441\u0456\u0445 \u0457\u0457 \u043f\u0456\u0434\u0442\u0435\u043a
+MainWindow.dialog.share.sharedircontents.recursive=\u0406 \u0432\u043c\u0456\u0441\u0442\u0443 \u0432\u0441\u0456\u0445 \u0457\u0457 \u043f\u0456\u0434\u0442\u0435\u043a
 globalmanager.download.remove.veto=\u041e\u043f\u0435\u0440\u0430\u0446\u0456\u044f \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u0437\u0430\u0431\u043e\u0440\u043e\u043d\u0435\u043d\u0430
-plugin.sharing.download.remove.veto=\u0426\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0430 \u0432\u0456\u0434\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u0434\u043e \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0438\u0445 \u0440\u043e\u0437\u0434\u0430\u0447.\n\u0414\u043b\u044f \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0432\u0438\u043b\u0443\u0447\u0456\u0442\u044c \u0457\u0457 \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0435 \u0434\u0436\u0435\u0440\u0435\u043b\u043e: go to Tools->My Classic-Shares.
+plugin.sharing.download.remove.veto=\u0426\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0430 \u0432\u0456\u0434\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u0434\u043e \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0438\u0445 \u0440\u043e\u0437\u0434\u0430\u0447.\n\u0414\u043b\u044f \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0432\u0438\u043b\u0443\u0447\u0456\u0442\u044c \u0457\u0457 \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0435 \u0434\u0436\u0435\u0440\u0435\u043b\u043e
 ConfigView.section.tracker.main=\u0413\u043e\u043b\u043e\u0432\u043d\u0430
 ConfigView.section.tracker.web=\u041c\u0435\u0440\u0435\u0436\u0430
 ConfigView.label.prioritizefirstpiece=\u041f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0435\u0440\u0448\u0438\u043c \u0456 \u043e\u0441\u0442\u0430\u043d\u043d\u0456\u043c \u0447\u0430\u0441\u0442\u0438\u043d\u0430\u043c \u0444\u0430\u0439\u043b\u0443 
-ConfigView.label.prioritizefirstpiece.tooltip=\u0412 \u043f\u0435\u0440\u0448\u0443 \u0447\u0435\u0440\u0433\u0443 \u043d\u0430\u043c\u0430\u0433\u0430\u0442\u0438\u0441\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u043f\u043e\u0447\u0430\u0442\u043e\u043a \u0444\u0430\u0439\u043b\u0443.\n\u0414\u043b\u044f \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0438 \u043f\u043e\u043f\u0435\u0440\u0435\u0434\u043d\u044c\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u0434\u0443.
+ConfigView.label.prioritizefirstpiece.tooltip=\u0412 \u043f\u0435\u0440\u0448\u0443 \u0447\u0435\u0440\u0433\u0443 \u043d\u0430\u043c\u0430\u0433\u0430\u0442\u0438\u0441\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u043f\u043e\u0447\u0430\u0442\u043e\u043a \u0456 \u043a\u0456\u043d\u0435\u0446\u044c \u0444\u0430\u0439\u043b\u0443.\n\u0414\u043b\u044f \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0438 \u043f\u043e\u043f\u0435\u0440\u0435\u0434\u043d\u044c\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u0434\u0443.
 ConfigView.section.file.confirm_data_delete=\u041f\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0436\u0435\u043d\u043d\u044f \u043f\u0440\u0438 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u0456
 ConfigView.section.file.confirm_data_delete.tooltip=\u041f\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0436\u0435\u043d\u043d\u044f \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u0434\u0430\u043d\u0438\u0445 \u043f\u0440\u0438 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u0456 "\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0456 \u0441\u0442\u0435\u0440\u0442\u0438"
 ConfigView.section.file.delete.include_files_outside_save_dir=\u041f\u0440\u0438 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u0456 \u0434\u0430\u043d\u0438\u0445, \u0434\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u0438 \u0442\u0430\u043a\u043e\u0436 \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 , \u0437\u0432'\u044f\u0437\u0430\u043d\u0456 \u043f\u043e\u0437\u0430 \u0442\u0435\u043a\u043e\u044e \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443
@@ -773,21 +773,21 @@ MySharesView.type.dircontentsrecursive=\u0412\u043c\u0456\u0441\u0442 \u0442\u04
 MySharesView.menu.remove=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 
 ConfigView.section.tracker.extensions=\u0420\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u043d\u044f
 ConfigView.section.tracker.sendpeerids=\u041f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u0438 \u0456\u0434\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0442\u043e\u0440 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u044e\u0447\u0438\u043c
-ConfigView.section.tracker.enableudp=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 UDP-\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0442\u0440\u0435\u043a\u0435\u0440\u0443
-plugin.sharing.torrent.remove.veto=\u0426\u044f \u0440\u0435\u0454\u0441\u0442\u0440\u0430\u0446\u0456\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u0432\u0456\u0434\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u0434\u043e \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u043e\u0457 \u0440\u043e\u0437\u0434\u0430\u0447\u0456.\n\u0414\u043b\u044f \u0457\u0457 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u0432\u0438\u043b\u0443\u0447\u0456\u0442\u044c \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0443 \u0440\u043e\u0437\u0434\u0430\u0447\u0443.: go to Tools->My Classic-Shares.
+ConfigView.section.tracker.enableudp=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b UDP \u0442\u0440\u0435\u043a\u0435\u0440\u0443
+plugin.sharing.torrent.remove.veto=\u0426\u044f \u0440\u0435\u0454\u0441\u0442\u0440\u0430\u0446\u0456\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u0432\u0456\u0434\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u0434\u043e \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u043e\u0457 \u0440\u043e\u0437\u0434\u0430\u0447\u0456.\n\u0414\u043b\u044f \u0457\u0457 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u0432\u0438\u043b\u0443\u0447\u0456\u0442\u044c \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0443 \u0440\u043e\u0437\u0434\u0430\u0447\u0443.
 plugin.download.remove.veto.notstopped=\u0414\u043b\u044f \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u043f\u0430\u043a\u0435\u0442\u0430 \u0437\u0443\u043f\u0438\u043d\u0456\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.
-plugin.sharing.remove.veto=\u0426\u044f \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0430 \u043d\u0430\u043b\u0435\u0436\u0438\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 "\u0412\u043c\u0456\u0441\u0442 \u043f\u0430\u043f\u043a\u0438" \u0456 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u0430.\n\u0412\u0438\u043b\u0443\u0447\u0456\u0442\u044c \u0442\u0435\u043a\u0443 \u0437 \u0440\u043e\u0437\u0434\u0430\u0447\u0456.
+plugin.sharing.remove.veto=\u0426\u044f \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0430 \u043d\u0430\u043b\u0435\u0436\u0438\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 "\u0412\u043c\u0456\u0441\u0442 \u0442\u0435\u043a\u0438" \u0456 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u0430.\n\u0412\u0438\u043b\u0443\u0447\u0456\u0442\u044c \u0442\u0435\u043a\u0443 \u0437 \u0440\u043e\u0437\u0434\u0430\u0447\u0456.
 GeneralView.label.hash.tooltip=\u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u0437\u0430\u043f\u0430\u043c'\u044f\u0442\u0430\u0442\u0438 \u0445\u0435\u0448
 ConfigView.section.tracker.maxpeersreturned=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432, \u044f\u043a\u0456 \u043f\u043e\u0432\u0435\u0440\u043d\u0443\u043b\u0438\u0441\u044f [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
-ConfigView.label.serverport=\u0412\u0445\u0456\u0434\u043d\u0438\u0439 TCP / UDP-\u043f\u043e\u0440\u0442 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f 
+ConfigView.label.serverport=TCP / UDP-\u043f\u043e\u0440\u0442 \u0432\u0445\u0456\u0434\u043d\u0438\u0445 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c
 ConfigView.label.serverport.tooltip=\u041d\u043e\u043c\u0435\u0440 \u043f\u043e\u0440\u0442\u0443 \u043f\u043e\u0432\u0438\u043d\u0435\u043d \u0431\u0443\u0442\u0438 \u0432 \u0434\u0456\u0430\u043f\u0430\u0437\u043e\u043d\u0456 \u0432\u0456\u0434 1 \u0434\u043e 65535, \u043a\u0440\u0456\u043c 6880, \u044f\u043a\u0438\u0439 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043e\u044e \u0434\u043b\u044f \u0432\u043b\u0430\u0441\u043d\u0438\u0445 \u0446\u0456\u043b\u0435\u0439.
-configureWizard.nat.server.tcp_listen_port=\u0412\u0445\u0456\u0434\u043d\u0438\u0439 TCP-\u043f\u043e\u0440\u0442 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f 
-ConfigView.section.sharing=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0430
-ConfigView.section.sharing.usessl=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 SSL \u0434\u043b\u044f \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0438\u0445 \u0440\u043e\u0437\u0434\u0430\u0447 (\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0443)
-ConfigView.section.style.dropdiraction=\u041e\u043f\u0446\u0456\u044f "Drag and Drop" \u0434\u043b\u044f \u0442\u0435\u043a
+configureWizard.nat.server.tcp_listen_port=TCP-\u043f\u043e\u0440\u0442 \u0432\u0445\u0456\u0434\u043d\u0438\u0445 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c
+ConfigView.section.sharing=\u041a\u043b\u0430\u0441\u0438\u0447\u043d\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0430
+ConfigView.section.sharing.usessl=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 SSL \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0438\u0447\u043d\u0438\u0445 \u0440\u043e\u0437\u0434\u0430\u0447 (\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0443)
+ConfigView.section.style.dropdiraction=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 "Drag and Drop" \u0434\u043b\u044f \u0442\u0435\u043a
 ConfigView.section.style.dropdiraction.opentorrents=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442
-ConfigView.section.style.dropdiraction.sharefolder=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0442\u0435\u043a\u0443
-ConfigView.section.style.dropdiraction.sharefoldercontents=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0432\u043c\u0456\u0441\u0442
+ConfigView.section.style.dropdiraction.sharefolder=\u0422\u0435\u043a\u0430 \u043a\u043b\u0430\u0441\u0438\u0447\u043d\u0438\u0445 \u0440\u043e\u0437\u0434\u0430\u0447
+ConfigView.section.style.dropdiraction.sharefoldercontents=\u0412\u043c\u0456\u0441\u0442 \u043a\u043b\u0430\u0441\u0438\u0447\u043d\u0438\u0445 \u0440\u043e\u0437\u0434\u0430\u0447
 #
 # 2.0.7.x
 #
@@ -795,14 +795,14 @@ Categories.all=\u0412\u0441\u0456
 Categories.uncategorized=\u0411\u0435\u0437 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0439
 CategoryAddWindow.message=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043d\u0430\u0437\u0432\u0443 \u043d\u043e\u0432\u043e\u0457 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457
 CategoryAddWindow.title=\u0414\u043e\u0434\u0430\u0442\u0438 \u043d\u043e\u0432\u0443 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u044e
-ConfigView.label.autoSeedingIgnoreInfo=\u0406\u0433\u043d\u043e\u0440\u043e\u0432\u0430\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u043a\u0456\u043d\u0435\u0446\u044c \u0447\u0435\u0440\u0433\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0456 \u043d\u0435 \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e. \u0426\u0456 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0435 \u043f\u043e\u0448\u0438\u0440\u044e\u044e\u0442\u044c\u0441\u044f \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0437\u0456 \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u043c "\u0412\u0438\u0449\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442". \u042f\u043a\u0449\u043e \u0432\u043e\u043d\u0438 \u043d\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0456, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0439\u0442\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f "0" \u0434\u043b\u044f \u0432\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044f \u0437 \u043f\u0440\u0430\u0432\u0438\u043b\u0430.
+ConfigView.label.autoSeedingIgnoreInfo=\u0406\u0433\u043d\u043e\u0440\u043e\u0432\u0430\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u043a\u0456\u043d\u0435\u0446\u044c \u0447\u0435\u0440\u0433\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0456 \u043d\u0435 \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e. \u0426\u0456 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0435 \u043f\u043e\u0448\u0438\u0440\u044e\u044e\u0442\u044c\u0441\u044f \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0437\u0456 \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u043c "\u0412\u0438\u0449\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442". \u042f\u043a\u0449\u043e \u0432\u043e\u043d\u0438 \u043d\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0456, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0439\u0442\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f "0" \u0434\u043b\u044f \u0432\u0438\u043d\u044f\u0442\u043a\u0443 \u0437 \u043f\u0440\u0430\u0432\u0438\u043b\u0430.
 ConfigView.label.directory=\u0422\u0435\u043a\u0430
 ConfigView.label.disconnetseed.tooltip=\u041f\u0440\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u043f\u0435\u0440\u0435\u0440\u0432\u0430\u0442\u0438 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0437 \u0441\u0456\u0434\u0435\u0440\u0430\u043c\u0438.\n\u0417\u0432\u2019\u044f\u0437\u043e\u043a \u0437 \u043d\u0438\u043c\u0438 \u043d\u0435 \u043e\u0431\u043e\u0432'\u044f\u0437\u043a\u043e\u0432\u0438\u0439.
-ConfigView.label.ignoreCase=\u041a\u0440\u0456\u043c \u0446\u0438\u0445
+ConfigView.label.ignoreCase=\u041d\u0435\u0445\u0442\u0443\u0432\u0430\u0442\u0438 \u0440\u0435\u0433\u0456\u0441\u0442\u0440\u043e\u043c
 ConfigView.label.ignoreSeeds=\u041a\u0440\u0456\u043c \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u0441\u0456\u0434\u0435\u0440\u0456\u0432 \u043c\u0435\u043d\u0448 \u044f\u043a
 ConfigView.label.importdirectory=\u0422\u0435\u043a\u0430 \u0456\u043c\u043f\u043e\u0440\u0442\u0443
 ConfigView.label.minPeersToBoostNoSeeds.tooltip=\u0412\u0441\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0431\u0435\u0437 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u044e\u0447\u0438\u0445 \u0441\u0456\u0434\u0435\u0440\u0456\u0432, \u0430\u0431\u043e \u0437 \u043c\u0435\u043d\u0448 \u044f\u043a\n\u0440\u0443\u0445\u0430\u0442\u0438 \u0434\u043e\u0433\u043e\u0440\u0438 \u0447\u0435\u0440\u0433\u0438
-ConfigView.label.minPeersToBoostNoSeeds=\u0417\u0430\u043d\u0438\u0436\u0435\u043d\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0434\u043b\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0431\u0435\u0437 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u044e\u0447\u0438\u0445 \u0430\u0431\u043e \u0457\u0445\u043d\u044c\u043e\u044e \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u043c\u0435\u043d\u0448 \u043d\u0456\u0436
+ConfigView.label.minPeersToBoostNoSeeds=\u0417\u0430\u043d\u0438\u0436\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0434\u043b\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0431\u0435\u0437 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u044e\u0447\u0438\u0445 \u0430\u0431\u043e \u0457\u0445\u043d\u044c\u043e\u044e \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u043c\u0435\u043d\u0448 \u043d\u0456\u0436
 ConfigView.label.minSeedingTime.tooltip=\u041f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043c\u043e\u0436\u0443\u0442\u044c \u0437\u0430 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u0447\u0430\u0441 \u0447\u0430\u0441\u0442\u043e \u0432\u0430\u0440\u0456\u044e\u0432\u0430\u0442\u0438\u0441\u044c, \u0449\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435 \u0434\u043e \u0447\u0430\u0441\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u0456 \u0437\u0443\u043f\u0438\u043d\u043a\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0443.\n\u0426\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u0430 \u0432\u0438\u0440\u0456\u0448\u0438\u0442\u0438 \u0442\u0430\u043a, \u0449\u043e \u0440\u043e\u0437\u0434\u0430\u0447\u0430 \u043d\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u043f\u0435\u0440\u0456\u043e\u0434 \u0447\u0430\u0441\u0443 \u043d\u0435 \u0437\u0443\u043f\u0438\u043d\u044f\u0442\u0438\u043c\u0435\u0442\u044c\u0441\u044f.\n\u041e\u0434\u043d\u0430\u043a \u0437\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0443 \u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432 \u0431\u0443\u0434\u044c-\u044f\u043a\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442.
 ConfigView.label.minSeedingTime=\u041c\u0456\u043d\u0456\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u0447\u0430\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445
 ConfigView.label.minSpeedForActiveDL.tooltip=\u0421\u043b\u043e\u0442 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437\u0430\u0439\u043c\u0430\u0454\u0442\u044c\u0441\u044f \u043d\u0430 30 \u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u043b\u044f \u0456\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u0457 \n\u043f\u0456\u0441\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u043d\u0435\u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043e\u0433\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0443
@@ -812,20 +812,20 @@ ConfigView.label.queue.debuglog=\u0417\u0430\u043f\u0438\u0441\u0443\u0432\u0430
 ConfigView.label.queue.debuglog.info=\u0412\u0438\u0434\u0430\u0432\u0430\u0442\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0436\u0435\u043d\u043d\u044f \u043f\u0440\u043e \u043f\u043e\u043c\u0438\u043b\u043a\u0438 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0456 \u0444\u0430\u0439\u043b \u043b\u043e\u0433\u0443.\n\u041d\u0430\u0432\u0456\u0442\u044c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0430, \u0446\u044f \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u0432\u0438\u0440\u0430\u0436\u0430\u0454 \u0441\u0442\u0430\u043d \u0442\u043e\u0440\u0435\u043d\u0442\u0443, \u0456 \u0447\u043e\u043c\u0443 \u0432\u043e\u043d\u0438 (\u043d\u0435)\u0431\u0443\u043b\u0438 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0456 \u0430\u0431\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0456 \u0432 \u0447\u0435\u0440\u0433\u0443.
 ConfigView.label.queue.minQueueingShareRatio=\u041d\u0435 \u0441\u0442\u0430\u0432\u0438\u0442\u0438 \u0432 \u0447\u0435\u0440\u0433\u0443 \u0456 \u043d\u0435 \u0437\u0443\u043f\u0438\u043d\u044f\u0442\u0438 \u0434\u043e \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0434\u043e \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0432\u0438\u0449\u0435
 ConfigView.label.ratio=\u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f
-ConfigView.label.removeOnStop=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u0437\u0456 \u0441\u043f\u0438\u0441\u043a\u0443 \u043f\u0456\u0441\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0457 \u0437\u0443\u043f\u0438\u043d\u043a\u0438
-ConfigView.label.savedirectory=\u0422\u0435\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0443
-ConfigView.label.seeding.autoReposition.tooltip=\u042f\u043a\u0449\u043e \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0430, \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 (\u0441\u0442\u043e\u0432\u043f\u0435\u0446\u044c '#') \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0443 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u043d\u0456\u0441\u0442\u044c \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u0440\u043e\u0437\u0434\u0430\u0447\u0456.\n\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0439\u0442\u0435, \u044f\u043a\u0449\u043e \u0412\u0438 \u0432\u0438\u043c\u043a\u043d\u0443\u043b\u0438 \u043f\u043e\u043a\u0430\u0437 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u0430\u043b\u0435 \u0431\u0430\u0436\u0430\u0454\u0442\u0435 \u0437\u043d\u0430\u0442\u0438 \u043f\u0440\u043e \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432.
+ConfigView.label.removeOnStop=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u0443 \u0441\u043f\u0438\u0441\u043a\u0443 \u043f\u0456\u0441\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0457 \u0437\u0443\u043f\u0438\u043d\u043a\u0438
+ConfigView.label.savedirectory=\u0422\u0435\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f
+ConfigView.label.seeding.autoReposition.tooltip=\u042f\u043a\u0449\u043e \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0430, \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 (\u0441\u0442\u043e\u0432\u043f\u0435\u0446\u044c '#') \u043f\u0440\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0443 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u043d\u0456\u0441\u0442\u044c \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u0440\u043e\u0437\u0434\u0430\u0447\u0456.\n\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0439\u0442\u0435, \u044f\u043a\u0449\u043e \u0412\u0438 \u0432\u0438\u043c\u043a\u043d\u0443\u043b\u0438 \u043f\u043e\u043a\u0430\u0437 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u0430\u043b\u0435 \u0431\u0430\u0436\u0430\u0454\u0442\u0435 \u0437\u043d\u0430\u0442\u0438 \u043f\u0440\u043e \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432.
 ConfigView.label.seeding.autoReposition=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0440\u043e\u0437\u043c\u0456\u0449\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0437\u0430 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0440\u043e\u0437\u0434\u0430\u0447\u0456
-ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=\u0427\u0430\u0441\u0442\u0430 \u043d\u0430\u044f\u0432\u043d\u0456\u0441\u0442\u044c \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437 \u043c\u0430\u043b\u043e\u044e \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u0441\u0456\u0434\u0435\u0440\u0456\u0432 \u0456 \u0432\u0435\u043b\u0438\u043a\u043e\u044e \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0432\u043a\u0430\u0437\u0443\u0454 \u043d\u0430 \u0442\u0435, \u0449\u043e \u0441\u0435\u0440\u0435\u0434 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u043d\u0430 \u0446\u0435\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435\u043c\u0430\u0454 \u043f\u043e\u0432\u043d\u043e\u0457 \u043a\u043e\u043f\u0456\u0457.\n\u0422\u043e\u043c\u0443 \u043d\u0435 \u0432\u0430\u0440\u0442\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u0449\u043e \u043f\u0440\u0438\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u044c \u043d\u0430\u044f\u0432\u043d\u0456\u0441\u0442\u044c \u043f\u043e\u0432\u043d\u043e\u0457 \u043a\u043e\u043f\u0456\u0457 \u0456 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0437\u043d\u0438\u0436\u0443\u044e\u0442\u044c \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0440\u043e\u0437\u0434\u0430\u0447\u0456.
-ConfigView.label.seeding.fakeFullCopySeedStart=K\u0440\u0456\u043c \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u0441\u0456\u0434\u0435\u0440\u0456\u0432 \u043d\u0435 \u043c\u0435\u043d\u0448, \u043d\u0456\u0436
-ConfigView.label.seeding.ignore=\u0406\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430
-ConfigView.label.seeding.ignore0Peers=\u0406\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u0449\u043e \u043d\u0435 \u043c\u0430\u044e\u0442\u044c \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432
-ConfigView.label.seeding.ignoreRatioPeers=\u0406\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u0449\u043e \u043c\u0430\u044e\u0442\u044c \u0431\u0456\u043b\u044c\u0448\u0435 1 \u0441\u0456\u0434\u0435\u0440\u0430 \u043d\u0430 \u043a\u043e\u0436\u043d\u0456
-ConfigView.label.seeding.ignoreShareRatio=\u0406\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u0449\u043e \u043c\u0430\u044e\u0442\u044c \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456
-ConfigView.label.seeding.ignore.header.evenFirstPriority=\u0406\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442, \u043d\u0430\u0432\u0456\u0442\u044c\n\u044f\u043a\u0449\u043e \u0434\u0456\u044e\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u0438\u0449\u043e\u0433\u043e \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443
+ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=\u0427\u0430\u0441\u0442\u0430 \u043d\u0430\u044f\u0432\u043d\u0456\u0441\u0442\u044c \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437 \u043c\u0430\u043b\u043e\u044e \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u0441\u0456\u0434\u0435\u0440\u0456\u0432 \u0456 \u0432\u0435\u043b\u0438\u043a\u043e\u044e \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0432\u043a\u0430\u0437\u0443\u0454 \u043d\u0430 \u0442\u0435, \u0449\u043e \u0441\u0435\u0440\u0435\u0434 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u043d\u0430 \u0446\u0435\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435\u043c\u0430 \u043f\u043e\u0432\u043d\u043e\u0457 \u043a\u043e\u043f\u0456\u0457.\n\u0422\u043e\u043c\u0443 \u043d\u0435 \u0432\u0430\u0440\u0442\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u0449\u043e \u043f\u0440\u0438\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u044c \u043d\u0430\u044f\u0432\u043d\u0456\u0441\u0442\u044c \u043f\u043e\u0432\u043d\u043e\u0457 \u043a\u043e\u043f\u0456\u0457 \u0456 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0437\u043d\u0438\u0436\u0443\u044e\u0442\u044c \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0440\u043e\u0437\u0434\u0430\u0447\u0456.
+ConfigView.label.seeding.fakeFullCopySeedStart=\u043a\u0440\u0456\u043c \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u043c\u0435\u043d\u0448\u0435, \u043d\u0456\u0436
+ConfigView.label.seeding.ignore=\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0435\u0445\u0442\u0443\u0432\u0430\u043d\u043d\u044f
+ConfigView.label.seeding.ignore0Peers=\u041d\u0435\u0445\u0442\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0430\u043c\u0438, \u044f\u043a\u0456 \u043d\u0435 \u043c\u0430\u044e\u0442\u044c \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432
+ConfigView.label.seeding.ignoreRatioPeers=\u041d\u0435\u0445\u0442\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0430\u043c\u0438, \u044f\u043a\u0456 \u043c\u0430\u044e\u0442\u044c \u0431\u0456\u043b\u044c\u0448\u0435 1 \u0441\u0456\u0434\u0435\u0440\u0430 \u043d\u0430 \u043a\u043e\u0436\u043d\u0456
+ConfigView.label.seeding.ignoreShareRatio=\u041d\u0435\u0445\u0442\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0430\u043c\u0438, \u044f\u043a\u0456 \u043c\u0430\u044e\u0442\u044c \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456
+ConfigView.label.seeding.ignore.header.evenFirstPriority=\u041d\u0435\u0445\u0442\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0430\u043c\u0438, \u043d\u0430\u0432\u0456\u0442\u044c\n\u044f\u043a\u0449\u043e \u0434\u0456\u044e\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u0438\u0449\u043e\u0433\u043e \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443
 ConfigView.label.seeding.ignore.header.rule=\u041f\u0440\u0430\u0432\u0438\u043b\u043e
 ConfigView.label.seeding.ignore.header.value=\u0417\u043d\u0430\u0447\u0435\u043d\u043d\u044f
-ConfigView.label.seeding.firstPriority.info=\u0412\u0438\u0449\u0438\u043c \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0437\u0430\u0432\u0436\u0434\u0438 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u044e\u0442\u044c\u0441\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u044f\u043a\u0456 \u043f\u0435\u0440\u0435\u0431\u0443\u0432\u0430\u044e\u0442\u044c \u043d\u0430 \u043f\u043e\u0447\u0430\u0442\u043a\u0443 \u0447\u0435\u0440\u0433\u0438. \u0422\u043e\u0440\u0435\u043d\u0442\u0438, \u044f\u043a\u0456 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u0430\u044e\u0442\u044c \u043a\u0440\u0438\u0442\u0435\u0440\u0456\u044f\u043c \u0432\u0438\u0449\u043e\u0433\u043e \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443, \u043d\u0435 \u0437\u0443\u043f\u0438\u043d\u044f\u044e\u0442\u044c\u0441\u044f \u0456 \u043d\u0435 \u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0447\u0435\u0440\u0433\u0443 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e. \u041f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e\u0441\u0442\u0456 \u0457\u043c \u0432\u0438\u0434\u0456\u043b\u044f\u0454\u0442\u044c\u0441\u044f \u0441\u043b\u043e\u0442 \u043e\u0434\u043d\u043e\u0447\u0430\u0441\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.
+ConfigView.label.seeding.firstPriority.info=\u0412\u0438\u0449\u0438\u043c \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0437\u0430\u0432\u0436\u0434\u0438 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u044e\u0442\u044c\u0441\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u044f\u043a\u0456 \u043f\u0435\u0440\u0435\u0431\u0443\u0432\u0430\u044e\u0442\u044c \u043d\u0430 \u043f\u043e\u0447\u0430\u0442\u043a\u0443 \u0447\u0435\u0440\u0433\u0438. \u0422\u043e\u0440\u0435\u043d\u0442\u0438, \u044f\u043a\u0456 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u0430\u044e\u0442\u044c \u043a\u0440\u0438\u0442\u0435\u0440\u0456\u044f\u043c \u0432\u0438\u0449\u043e\u0433\u043e \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443, \u043d\u0435 \u0437\u0443\u043f\u0438\u043d\u044f\u044e\u0442\u044c\u0441\u044f \u0456 \u043d\u0435 \u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0447\u0435\u0440\u0433\u0443 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e. \u041f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e\u0441\u0442\u0456 \u0457\u043c \u0432\u0438\u0431\u0438\u0440\u0430\u0454\u0442\u044c\u0441\u044f \u0441\u043b\u043e\u0442 \u043e\u0434\u043d\u043e\u0447\u0430\u0441\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.
 ConfigView.label.seeding.firstPriority.FP=\u0412\u0438\u0449\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442
 ConfigView.label.seeding.firstPriority=\u041f\u0440\u0438\u0432\u043b\u0430\u0441\u043d\u044e\u0432\u0430\u0442\u0438 \u0432\u0438\u0449\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0442\u043e\u0440\u0435\u043d\u0442\u0430\u043c
 ConfigView.label.seeding.firstPriority.following=\u0434\u043b\u044f \u044f\u043a\u0438\u0445 \u0434\u0456\u0439\u0441\u043d\u0456 \u043d\u0438\u0436\u0447\u0435\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0456 \u0443\u043c\u043e\u0432\u0438:
@@ -835,24 +835,24 @@ ConfigView.label.seeding.firstPriority.DLMinutes=\u0427\u0430\u0441, \u044f\u043
 ConfigView.label.seeding.numPeersAsFullCopy.tooltip=\u0420\u043e\u0437\u0440\u0430\u0445\u043e\u0432\u0443\u044e\u0447\u0438 \u043f\u043e\u0432\u043d\u0443 \u043a\u043e\u043f\u0456\u044e \u043d\u0430 \u043a\u043e\u0436\u043d\u0456 \u0425 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432, \u0412\u0438 \u0437\u043d\u0438\u0436\u0443\u0454\u0442\u0435 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437 \u0431\u0456\u043b\u044c\u0448\u043e\u044e \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432.\n\u0428\u0432\u0438\u0434\u0448\u0435 \u0437\u0430 \u0432\u0441\u0435, \u0442\u0430\u043a\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0442\u0430\u043a\u043e\u0436 \u043c\u0430\u044e\u0442\u044c \u0432\u0435\u043b\u0438\u043a\u0438\u0439 \u0442\u0440\u0430\u0444\u0456\u043a. \u0426\u044f \u0444\u0443\u043d\u043a\u0446\u0456\u044f \u043d\u0435 \u0437\u043c\u0456\u043d\u044e\u0454 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447 \u0432 \u0441\u0442\u043e\u0432\u043f\u0446\u0456 '# \u0440\u043e\u0437\u0434\u0430\u0447\u0456' 
 ConfigView.label.seeding.numPeersAsFullCopy=\u0420\u043e\u0437\u0440\u0430\u0445\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043d\u0430\u044f\u0432\u043d\u0456\u0441\u0442\u044c \u043f\u043e\u0432\u043d\u043e\u0457 \u043a\u043e\u043f\u0456\u0457 \u043d\u0430 \u043a\u043e\u0436\u043d\u0456\n[0 : \u0431\u0435\u0437 \u043f\u0440\u0438\u043f\u0443\u0449\u0435\u043d\u044c]
 ConfigView.label.seeding.preferLargerSwarms.tooltip=\u042f\u043a\u0449\u043e \u0412\u0438 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u0440\u043e\u0437\u0434\u0430\u0454\u0442\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u043d\u0435 \u0431\u0430\u0433\u0430\u0442\u044c\u043e\u043c \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u0442\u044c\u0441\u044f "\u043f\u0435\u0440\u0435\u0432\u0430\u0433\u0430 \u0432\u0435\u043b\u0438\u043a\u0438\u0445 \u0433\u0440\u0443\u043f".\n\u0412 \u0432\u0438\u043f\u0430\u0434\u043a\u0443 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0440\u043e\u0437\u043f\u043e\u0432\u0441\u044e\u0434\u0436\u0435\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 - "\u043f\u0435\u0440\u0435\u0432\u0430\u0433\u0430 \u043c\u0430\u043b\u0438\u0445 \u0433\u0440\u0443\u043f".
-ConfigView.label.seeding.preferLargerSwarms=\u0421\u0435\u0440\u0435\u0434 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u0432\u0456\u0434\u0434\u0430\u0432\u0430\u0442\u0438 \u043f\u0435\u0440\u0435\u0432\u0430\u0433\u0438 \u043d\u0430\u0439\u043f\u043e\u0448\u0438\u0440\u0435\u043d\u0456\u0448\u0438\u043c.
-ConfigView.label.seeding.rankType.none.tooltip=\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0437\u0430 \u043d\u043e\u043c\u0435\u0440\u0430\u043c\u0438 # \u0441\u0442\u043e\u0432\u043f\u0446\u044f
+ConfigView.label.seeding.preferLargerSwarms=\u0421\u0435\u0440\u0435\u0434 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u043e\u0434\u043d\u0430\u043a\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u0432\u0456\u0434\u0434\u0430\u0432\u0430\u0442\u0438 \u043f\u0435\u0440\u0435\u0432\u0430\u0433\u0438 \u043d\u0430\u0439\u043f\u043e\u0448\u0438\u0440\u0435\u043d\u0456\u0448\u0438\u043c.
+ConfigView.label.seeding.rankType.none.tooltip=\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0437\u0430 \u0441\u0442\u043e\u0432\u043f\u0446\u0435\u043c #
 ConfigView.label.seeding.rankType.none=\u041d\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438
 ConfigView.label.seeding.rankType.peer.tooltip=\u0427\u0438\u043c \u0431\u0456\u043b\u044c\u0448\u0435 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0456 \u043c\u0435\u043d\u0448\u0435 \u0441\u0456\u0434\u0435\u0440\u0456\u0432, \u0442\u0438\u043c \u0432\u0438\u0449\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\n\u0426\u0435\u0439 \u0442\u0438\u043f \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u0437\u043c\u0435\u043d\u0448\u0443\u0454 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432, \u044f\u043a\u0438\u0439 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u0431\u0443\u0442\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u0438\u043c\u0438 \u0434\u043b\u044f \u0437\u0431\u0456\u043b\u044c\u0448\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 ConfigView.label.seeding.rankType.peer=\u0417\u0430 \u043d\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f\u043c \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432
-ConfigView.label.seeding.rankType.peerSeed.options=\u0421\u0456\u0434\u0435\u0440\u0438: \u0417\u0430 \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f\u043c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
+ConfigView.label.seeding.rankType.peerSeed.options=\u0417\u0430 \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f\u043c \u0441\u0456\u0434\u0435\u0440\u0456\u0432 \u0434\u043e \u0443\u0447\u0430\u043d\u0438\u043a\u0456\u0432 (\u043e\u043f\u0446\u0456\u0457)
 ConfigView.label.seeding.rankType.peerSeed.tooltip=\u0427\u0438\u043c \u0432\u0438\u0449\u0435 \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f, \u0442\u0438\u043c \u0432\u0438\u0449\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442
 ConfigView.label.seeding.rankType.peerSeed=\u0417\u0430 \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f\u043c \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0434\u043e \u0441\u0456\u0434\u0435\u0440\u0456\u0432
 ConfigView.label.seeding.rankType.seed.fallback=\u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438\u0441\u044f \u0434\u043e \u043a\u043e\u0435\u0444\u0456\u0446\u0456\u0454\u043d\u0442\u0443 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0447\u0435\u0440\u0435\u0437\n [0 : \u043d\u0456\u043a\u043e\u043b\u0438 \u043d\u0435 \u043f\u043e\u0432\u0435\u0440\u0442\u0430\u0442\u0438\u0441\u044f]
-ConfigView.label.seeding.rankType.seed.options=\u041b\u0438\u0448\u0435 \u0437\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u0441\u0456\u0434\u0435\u0440\u0456\u0432
+ConfigView.label.seeding.rankType.seed.options=\u041b\u0438\u0448\u0435 \u0437\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u0441\u0456\u0434\u0435\u0440\u0456\u0432 (\u043e\u043f\u0446\u0456\u0457)
 ConfigView.label.seeding.rankType.seed.tooltip=\u0427\u0438\u043c \u043c\u0435\u043d\u0448\u0435 \u0441\u0456\u0434\u0435\u0440\u0456\u0432, \u0442\u0438\u043c \u043d\u0438\u0436\u0447\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442
-ConfigView.label.seeding.rankType.seed=\u041b\u0438\u0448\u0435 \u0437\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u0440\u043e\u0437\u0434\u0430\u0447
+ConfigView.label.seeding.rankType.seed=\u041b\u0438\u0448\u0435 \u0437\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044e \u0441\u0456\u0434\u0435\u0440\u0456\u0432
 ConfigView.label.seeding.rankType.timedRotation.tooltip=\u0412\u0441\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0437\u0430 \u0447\u0435\u0440\u0433\u043e\u044e \u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c \u0440\u043e\u0437\u0434\u0430\u0447\u0456.\n\u0427\u0430\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0437\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u043e\u043f\u0446\u0456\u0457 '\u041c\u0456\u043d\u0456\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u0447\u0430\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456'
 ConfigView.label.seeding.rankType.timedRotation=\u0420\u0456\u0432\u043d\u043e\u043c\u0456\u0440\u043d\u043e \u0437\u043c\u0456\u043d\u044e\u0454\u0442\u044c\u0441\u044f \u0437 \u0447\u0430\u0441\u043e\u043c
-ConfigView.label.seeding.rankType.tooltip=\u0422\u043e\u0440\u0435\u043d\u0442\u0438 \u0437 \u043d\u0430\u0439\u0432\u0438\u0449\u0438\u043c \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e.\n\u042f\u043a\u0449\u043e \u0442\u043e\u0440\u0435\u043d\u0442 \u043e\u0434\u0435\u0440\u0436\u0443\u0454 \u0432\u0438\u0449\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442, \u0442\u043e\u0440\u0435\u043d\u0442 \u043d\u0438\u0436\u0447\u043e\u0433\u043e \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u0437\u0443\u043f\u0438\u043d\u044f\u0454\u0442\u044c\u0441\u044f \u0456 \u043f\u043e\u0432\u0435\u0440\u0442\u0430\u0454\u0442\u044c\u0441\u044f \u0432 \u0447\u0435\u0440\u0433\u0443.\n\n\u041b\u0438\u0448\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u044f\u043a\u0456 \u0441\u0442\u043e\u044f\u0442\u044c \u0432 \u0447\u0435\u0440\u0437\u0456, \u043c\u043e\u0436\u0443\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u0443\u0432\u0430\u0442\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e.\n\u0417\u0443\u043f\u0438\u043d\u0435\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u043d\u0456\u043a\u043e\u043b\u0438 \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u044c\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e.
+ConfigView.label.seeding.rankType.tooltip=\u0422\u043e\u0440\u0435\u043d\u0442\u0438 \u0437 \u043d\u0430\u0439\u0432\u0438\u0449\u0438\u043c \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e.\n\u042f\u043a\u0449\u043e \u0442\u043e\u0440\u0435\u043d\u0442 \u043e\u0442\u0440\u0438\u043c\u0443\u0454 \u0432\u0438\u0449\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442, \u0442\u043e\u0440\u0435\u043d\u0442 \u043d\u0438\u0436\u0447\u043e\u0433\u043e \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u0437\u0443\u043f\u0438\u043d\u044f\u0454\u0442\u044c\u0441\u044f \u0456 \u043f\u043e\u0432\u0435\u0440\u0442\u0430\u0454\u0442\u044c\u0441\u044f \u0432 \u0447\u0435\u0440\u0433\u0443.\n\n\u041b\u0438\u0448\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u044f\u043a\u0456 \u0441\u0442\u043e\u044f\u0442\u044c \u0432 \u0447\u0435\u0440\u0437\u0456, \u043c\u043e\u0436\u0443\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u0443\u0432\u0430\u0442\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e.\n\u0417\u0443\u043f\u0438\u043d\u0435\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u043d\u0456\u043a\u043e\u043b\u0438 \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u044c\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e.
 ConfigView.label.seeding.rankType=\u041f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0432\u0438\u0437\u043d\u0430\u0447\u0430\u0454\u0442\u044c\u0441\u044f:
-ConfigView.label.stopAfterMinutes=\u0414\u0456\u044e\u0447\u0443 \u0440\u043e\u0437\u0434\u0430\u0447\u0443 \u0437\u0443\u043f\u0438\u043d\u044f\u0442\u0438 \u0442\u0456\u043b\u044c\u043a\u0438 \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0447\u0430\u0441\u0443
-ConfigView.label.switchpriority.tooltip=\u041d\u0438\u0437\u044c\u043a\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0437\u043d\u0438\u0436\u0443\u0454 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u0432\u0438\u0434\u0456\u043b\u0435\u043d\u0443 \u0442\u043e\u0440\u0435\u043d\u0442\u0443.
+ConfigView.label.stopAfterMinutes=\u0427\u0438\u043d\u043d\u0443 \u0440\u043e\u0437\u0434\u0430\u0447\u0443 \u0437\u0443\u043f\u0438\u043d\u044f\u0442\u0438 \u043b\u0438\u0448\u0435 \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0447\u0430\u0441\u0443
+ConfigView.label.switchpriority.tooltip=\u041d\u0438\u0437\u044c\u043a\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0437\u043d\u0438\u0436\u0443\u0454 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u0432\u0438\u0431\u0440\u0430\u043d\u0443 \u0442\u043e\u0440\u0435\u043d\u0442\u0443.
 ConfigView.pluginlist.info=\u041d\u0438\u0436\u0447\u0435 \u043d\u0430\u0432\u0435\u0434\u0435\u043d\u0456 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u0456 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f. \u0414\u0435\u044f\u043a\u0456 \u0437 \u043d\u0438\u0445 \u043c\u043e\u0436\u0443\u0442\u044c \u043d\u0435 \u043c\u0430\u0442\u0438 \u043f\u0430\u043d\u0435\u043b\u0456 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c.
 ConfigView.pluginlist.noplugins=\u041d\u0456\u044f\u043a\u0438\u0445 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e.
 ConfigView.section.pluginslist=\u0421\u043f\u0438\u0441\u043e\u043a
@@ -865,15 +865,15 @@ ConfigView.section.queue=\u0427\u0435\u0440\u0433\u0430
 ConfigView.section.torrents=\u0422\u043e\u0440\u0435\u043d\u0442\u0438
 ConfigView.text.all=\u0432\u0441\u0456
 ConfigView.text.hours=\u0433\u043e\u0434\u0438\u043d
-ConfigView.text.ignoreRule=\u041d\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u043e
+ConfigView.text.ignoreRule=\u041f\u0440\u0430\u0432\u0438\u043b\u043e \u043d\u0435\u0445\u0442\u0443\u0432\u0430\u043d\u043d\u044f
 ConfigView.text.ignore=\u041d\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438
 ConfigView.text.minutes=\u0445\u0432\u0438\u043b\u0438\u043d
 ConfigView.text.neverIgnore=\u041d\u0456\u043a\u043e\u043b\u0438 \u043d\u0435 \u0456\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438
-ConfigView.text.any=\u043a\u043e\u0436\u043d\u0456
-DownloadManager.error.datamissing=\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043d\u044c\u043e \u0434\u0430\u043d\u0438\u0445!
+ConfigView.text.any=\u0431\u0443\u0434\u044c-\u044f\u043a\u0456
+DownloadManager.error.datamissing=\u0406\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u0432\u0442\u0440\u0430\u0447\u0435\u043d\u0430
 MainWindow.menu.file.open.torrentforseeding=\u0422\u043e\u0440\u0435\u043d\u0442 (\u0434\u043b\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456)
 MainWindow.menu.language.refresh=&\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438
-ManagerItem.forced=\u041f\u0440\u0438\u0448\u0432\u0438\u0434\u0448\u0435\u043d\u0430
+ManagerItem.forced=\u041f\u0440\u0438\u0441\u043a\u043e\u0440\u0435\u043d\u0430
 ManagerItem.queued=\u0423 \u0447\u0435\u0440\u0437\u0456
 MySeedersView.header=\u0417\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438
 TableColumn.header.availability.info=\u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0445 \u043a\u043e\u043f\u0456\u0439
@@ -886,7 +886,7 @@ MyTorrentsView.menu.forceStart=&\u041f\u0440\u0438\u0448\u0432\u0438\u0434\u0448
 MyTorrentsView.menu.queue=&\u0427\u0435\u0440\u0433\u0430
 MyTorrentsView.menu.setCategory.add=&\u0414\u043e\u0434\u0430\u0442\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u044e...
 MyTorrentsView.menu.setCategory=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u044e
-TableColumn.header.savepath=\u041f\u0430\u043f\u043a\u0430 \u0434\u043b\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
+TableColumn.header.savepath=\u0422\u0435\u043a\u0430 \u0434\u043b\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
 TableColumn.header.SeedingRank=\u041f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 TableColumn.header.totalspeed.info=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0432\u0441\u0456\u0445 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432
 TableColumn.header.totalspeed=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c
@@ -899,14 +899,14 @@ StartStopRules.ratioMet=\u0421\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u
 StartStopRules.shareRatioMet=\u0421\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456 O\u041a
 StartStopRules.waiting=\u041e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f
 StartStopRules.firstPriority=\u0412\u0438\u0449\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442
-ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0432\u043c\u0456\u0441\u0442 \u0442\u0435\u043a\u0438 \u0456 \u0432\u0441\u0456\u0445 \u0457\u0457 \u043f\u0456\u0434\u0442\u0435\u043a
+ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=\u0412\u043c\u0456\u0441\u0442 \u043a\u043b\u0430\u0441\u0438\u0447\u043d\u0438\u0445 \u0440\u043e\u0437\u0434\u0430\u0447 (\u0432\u0440\u0430\u0445\u043e\u0432\u0443\u044e\u0447\u0438 \u043f\u0456\u0434\u0442\u0435\u043a\u0438)
 DownloadManager.error.unabletostartserver=\u0417\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0435 \u0432\u0456\u0434\u0431\u0443\u0432\u0441\u044f - \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0445\u0456\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0443 / \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043d\u0438\u0445 Firewall-\u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \u0434\u043b\u044f \u0440\u043e\u0431\u043e\u0442\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0443
 GeneralView.label.creationdate=\u0421\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0439:
-ConfigView.section.tracker.announcescrapepercentage=\u041d\u0430\u043a\u043e\u043f\u0438\u0447\u0443\u0432\u0430\u043b\u044c\u043d\u0438\u0439 \u0456\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u044f\u043a \u0432\u0456\u043a \u0430\u043d\u043e\u043d\u0441\u0443\n\u0422\u043e\u0431\u0442\u043e 200 = 2:1. [0 : \u0432\u0438\u0437\u043d\u0430\u0447\u0430\u0454\u0442\u044c\u0441\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0435\u043c]
+ConfigView.section.tracker.announcescrapepercentage=\u0406\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0441\u0445\u043e\u0432\u0438\u0449\u0430 \u044f\u043a % \u0432\u0456\u043a\u0443 \u0430\u043d\u043e\u043d\u0441\u0443\n\u0422\u043e\u0431\u0442\u043e 200 = 2:1. [0 : \u0432\u0438\u0437\u043d\u0430\u0447\u0430\u0454\u0442\u044c\u0441\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0435\u043c]
 ManagerItem.stopping=\u0417\u0443\u043f\u0438\u043d\u043a\u0430
 ConfigView.section.tracker.announcecacheperiod=\u041a\u0435\u0448 \u0430\u043d\u043e\u043d\u0441\u0430 (\u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434)
-ConfigView.section.tracker.scrapecacheperiod=\u041d\u0430\u043a\u043e\u043f\u0438\u0447\u0443\u0432\u0430\u043b\u044c\u043d\u0438\u0439 \u043a\u0435\u0448 (\u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434)
-ConfigView.section.tracker.scrapeandcache=\u041d\u0430\u043a\u043e\u043f\u0438\u0447\u0443\u0432\u0430\u0447 \u0456 \u043a\u0435\u0448
+ConfigView.section.tracker.scrapecacheperiod=\u041a\u0435\u0448 \u0441\u0445\u043e\u0432\u0438\u0449\u0430 (\u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434)
+ConfigView.section.tracker.scrapeandcache=\u0421\u0445\u043e\u0432\u0438\u0449\u0435 \u0456 \u043a\u0435\u0448
 ConfigView.section.tracker.announcecacheminpeers=\u041a\u0435\u0448 \u0430\u043d\u043e\u043d\u0441\u0456\u0432, \u0432\u0440\u0430\u0445\u043e\u0432\u0443\u044e\u0447\u0438 \u043f\u043e\u0440\u0456\u0433 \u0434\u043b\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0456\u0432
 MyTrackerView.scrapes=\u041f\u043e\u043c\u0438\u043b\u043a\u043e\u0432\u0438\u0439
 fileDownloadWindow.retry=\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0438
@@ -914,7 +914,7 @@ MyTrackerView.bytesin=\u0412 \u0431\u0430\u0439\u0442\u0430\u0445
 MyTrackerView.bytesinave=\u0421\u0435\u0440\u0435\u0434\u043d\u0454 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u0438\u0445 \u0431\u0430\u0439\u0442\u0456\u0432 
 MyTrackerView.bytesout=\u0412\u0438\u0441\u043b\u0430\u043d\u0456 \u0431\u0430\u0439\u0442\u0438
 MyTrackerView.bytesoutave=\u0421\u0435\u0440\u0435\u0434\u043d\u0454 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0432\u0438\u0441\u043b\u0430\u043d\u0438\u0445 \u0431\u0430\u0439\u0442\u0456\u0432
-ConfigView.section.file.max_open_files=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438\u0445 \u0444\u0430\u0439\u043b\u0456\u0432 \u0434\u043b\u044f \u0447\u0438\u0442\u0430\u043d\u043d\u044f \u0430\u0431\u043e \u0437\u0430\u043f\u0438\u0441\u0443\n[0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0438\u0439]
+ConfigView.section.file.max_open_files=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438\u0445 \u0444\u0430\u0439\u043b\u0456\u0432 \u0434\u043b\u044f \u0447\u0438\u0442\u0430\u043d\u043d\u044f \u0430\u0431\u043e \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f\n[0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0438\u0439]
 ConfigView.section.file.max_open_files.tooltip=\u041a\u043e\u0440\u0438\u0441\u043d\u043e \u043f\u0440\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437 \u0441\u043e\u0442\u043d\u044f\u043c\u0438, \u0442\u0438\u0441\u044f\u0447\u0430\u043c\u0438 \u0444\u0430\u0439\u043b\u0456\u0432 \u0430\u0431\u043e \u044f\u043a\u0449\u043e \u0434\u043e\u0441\u044f\u0433\u043d\u0443\u0442\u0456 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u041e\u0421 \u0449\u043e\u0434\u043e \u043a\u0456\u043b\u044c\u043a\u043e\u0441\u0442\u0456 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438\u0445 \u0444\u0430\u0439\u043b\u0456\u0432
 ConfigView.section.proxy=\u041f\u0440\u043e\u043a\u0441\u0456
 ConfigView.section.proxy.enable_proxy=\u0414\u043e\u0441\u0442\u0443\u043f \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u043e\u043a\u0441\u0456-\u0441\u0435\u0440\u0432\u0435\u0440
@@ -932,12 +932,12 @@ AlertMessageBox.warning=\u0423\u0432\u0430\u0433\u0430
 AlertMessageBox.comment=\u0406\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f
 AlertMessageBox.information=\u0406\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f
 AlertMessageBox.unread=\u041d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u0456 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f - \u043a\u043b\u0430\u0446\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u043d\u0443\u0442\u0438 \u0457\u0445.
-SharedPortServer.alert.selectorfailed=\u041d\u0435 \u0432\u0434\u0430\u0454\u0442\u044c\u0441\u044f \u0432\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0440\u0438\u0439\u043e\u043c \u0434\u0430\u043d\u0438\u0445.\n\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u0432\u0430\u0448 \u0431\u0440\u0430\u043d\u0434\u043c\u0430\u0443\u0435\u0440, \u0449\u043e\u0431 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 java(w).exe \u043c\u0430\u043b\u0430 \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c \u043e\u0442\u0440\u0438\u043c\u0443\u0432\u0430\u0442\u0438 \u0456 \u0432\u0456\u0434\u0434\u0430\u0432\u0430\u0442\u0438 \u0434\u0430\u043d\u0456.
-Tracker.alert.listenfail=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0456 \u043f\u043e\u0440\u0442\u0443 \u0437\u0432'\u044f\u0437\u043a\u0443 %1.\n\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435, \u0447\u0438 \u043d\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0446\u0435\u0439 \u043f\u043e\u0440\u0442 \u0456\u043d\u0448\u0438\u043c\u0438 \u0434\u043e\u0434\u0430\u0442\u043a\u0430\u043c\u0438,\n\u0443 \u0442\u043e\u043c\u0443 \u0447\u0438\u0441\u043b\u0456 \u0456 \u0456\u043d\u0448\u043e\u044e \u043a\u043e\u043f\u0456\u0454\u044e Vuze.
+SharedPortServer.alert.selectorfailed=\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u0432\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0440\u0438\u0439\u043e\u043c \u0434\u0430\u043d\u0438\u0445.\n\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u0432\u0430\u0448 \u0431\u0440\u0430\u043d\u0434\u043c\u0430\u0443\u0435\u0440, \u0449\u043e\u0431 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 java(w).exe \u043c\u0430\u043b\u0430 \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c \u043e\u0442\u0440\u0438\u043c\u0443\u0432\u0430\u0442\u0438 \u0456 \u0432\u0456\u0434\u0434\u0430\u0432\u0430\u0442\u0438 \u0434\u0430\u043d\u0456.
+Tracker.alert.listenfail=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0456 \u043f\u043e\u0440\u0442\u0443 \u0437\u0432'\u044f\u0437\u043a\u0443 %1.\n\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435, \u0447\u0438 \u043d\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0446\u0435\u0439 \u043f\u043e\u0440\u0442 \u0456\u043d\u0448\u0438\u043c\u0438 \u0437\u0430\u0441\u0442\u043e\u0441\u0443\u043d\u043a\u0430\u043c\u0438,\n\u0437\u043e\u043a\u0440\u0435\u043c\u0430 \u0456 \u0456\u043d\u0448\u043e\u044e \u043a\u043e\u043f\u0456\u0454\u044e Vuze.
 DiskManager.alert.movefileexists=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043d\u043d\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043ba.\n\u0424\u0430\u0439\u043b %1 \u0432\u0436\u0435 \u0456\u0441\u043d\u0443\u0454 \u0432 \u043a\u0456\u043d\u0446\u0435\u0432\u0456\u0439 \u0442\u0435\u0446\u0456.
 DiskManager.alert.movefilefails=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043d\u043d\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0443.\n\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443 %1 \u043d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f, %2
 DiskManager.alert.movefilerecoveryfails=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u043f\u0456\u0441\u043b\u044f \u043d\u0435\u0432\u0434\u0430\u043b\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443 %1, %2
-ConfigView.section.tracker.logenable=\u041f\u0435\u0440\u0456\u043e\u0434\u0438\u0447\u043d\u0438\u0439 \u043b\u043e\u0433 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0432 'tracker.log'
+ConfigView.section.tracker.logenable=\u041f\u0435\u0440\u0456\u043e\u0434\u0438\u0447\u043d\u0435 \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0432 'tracker.log'
 SpeedView.stats.title=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430
 SpeedView.stats.total=\u0412\u0441\u044c\u043e\u0433\u043e
 SpeedView.stats.session=\u041f\u043e\u0442\u043e\u0447\u043d\u0430 \u0441\u0435\u0441\u0456\u044f
@@ -948,15 +948,15 @@ SpeedView.stats.ratio=\u0421\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u04
 SpeedView.stats.uptime=\u0427\u0430\u0441 \u0431\u0435\u0437\u043f\u0435\u0440\u0435\u0440\u0432\u043d\u043e\u0457 \u0440\u043e\u0431\u043e\u0442\u0438 (\u0443 \u0433\u043e\u0434\u0438\u043d\u0430\u0445)
 SpeedView.stats.now=\u0417\u0430\u0440\u0430\u0437
 SpeedView.stats.now.tooltip=\u0412\u0441\u044c\u043e\u0433\u043e (\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b)
-AutoMigration.useralert=\u0406\u043c\u043f\u043e\u0440\u0442 \u0444\u0430\u0439\u043b\u0456\u0432 \u0456 \u043f\u0430\u043f\u043e\u043a \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u0457:\n\n%1\n\u0412 \u0440\u0430\u0437\u0456 \u043d\u0435\u0432\u0434\u0430\u0447\u0456 \u0456\u043c\u043f\u043e\u0440\u0442 \u043c\u0430\u0454 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u0438\u0441\u044f \u0432\u0440\u0443\u0447\u043d\u0443.\n\u041d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u0430\u043f\u043a\u0438 \u0434\u043b\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0432 \u0432\u0438\u043f\u0430\u0434\u043a\u0443 \u0456\u043c\u043f\u043e\u0440\u0442\u0443!
+AutoMigration.useralert=\u0406\u043c\u043f\u043e\u0440\u0442 \u0444\u0430\u0439\u043b\u0456\u0432 \u0456 \u0442\u0435\u043a \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u0457:\n\n%1\n\u0412 \u0440\u0430\u0437\u0456 \u043d\u0435\u0432\u0434\u0430\u0447\u0456 \u0456\u043c\u043f\u043e\u0440\u0442 \u043c\u0430\u0454 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u0438\u0441\u044f \u0432\u0440\u0443\u0447\u043d\u0443.\n\u041d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0432 \u0432\u0438\u043f\u0430\u0434\u043a\u0443 \u0456\u043c\u043f\u043e\u0440\u0442\u0443!
 #
 # > 2.0.8.0
 #
 OpenTorrentWindow.title=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442(\u0438)
 OpenTorrentWindow.message=\u0415\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e
 OpenTorrentWindow.addFiles=&\u0414\u043e\u0434\u0430\u0442\u0438 \u0444\u0430\u0439\u043b
-OpenTorrentWindow.dataLocation=\u041c\u0456\u0441\u0446\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0434\u0430\u043d\u0438\u0445:
-OpenTorrentWindow.startMode=\u0414\u043e\u0434\u0430\u0442\u0438 \u0440\u0435\u0436\u0438\u043c
+OpenTorrentWindow.dataLocation=\u0420\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0434\u0430\u043d\u0438\u0445:
+OpenTorrentWindow.startMode=\u0420\u0435\u0436\u0438\u043c \u0434\u043e\u0434\u0430\u0432\u0430\u043d\u043d\u044f
 OpenTorrentWindow.startMode.queued=\u0423 \u0447\u0435\u0440\u0437\u0456
 OpenTorrentWindow.startMode.stopped=\u0417\u0443\u043f\u0438\u043d\u0435\u043d\u0438\u0439
 OpenTorrentWindow.startMode.forceStarted=\u041f\u0440\u0438\u0448\u0432\u0438\u0434\u0448\u0435\u043d\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a
@@ -968,53 +968,53 @@ TableColumn.header.remaining=\u0417\u0430\u043b\u0438\u0448\u0438\u043b\u043e\u0
 ConfigView.section.tracker.enablecompact=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u0438\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043e\u043f\u043e\u0432\u0456\u0449\u0435\u043d\u043d\u044f
 ConfigView.section.tracker.enablekey=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0443 \u043a\u043b\u044e\u0447\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u0434\u043b\u044f \u043f\u0456\u0434\u0432\u0438\u0449\u0435\u043d\u043e\u0457 \u0431\u0435\u0437\u043f\u0435\u043a\u0438
 ConfigView.section.file.perf=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0456
-ConfigView.section.file.perf.explain=\u041e\u0431\u0435\u0440\u0435\u0436\u043d\u043e - \u043d\u0435\u043e\u0431\u0434\u0443\u043c\u0430\u043d\u0456 \u0437\u043c\u0456\u043d\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0456\u0432 \u043c\u043e\u0436\u0443\u0442\u044c \u043c\u0430\u0442\u0438 \u043f\u0440\u043e\u0442\u0438\u043b\u0435\u0436\u043d\u0438\u0439 \u0435\u0444\u0435\u043a\u0442 \u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.\n\u0412\u0438\u043c\u0430\u0433\u0430\u0454\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a. \u041f\u0440\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043d\u0456\u0439 \u043f\u0430\u043c'\u044f\u0442\u0456 \u043f\u043e\u0434\u0443\u043c\u0430\u0439\u0442\u0435 \u043f\u0440\u043e \u0437\u043d\u0438\u0436\u0435\u043d\u043d\u044f \u043a\u0456\u043b\u044c\u043a\u043e\u0441\u0442\u0456 \u0437\u0432'\u044f\u0437\u043a\u0456\u0432 \u0442\u043e\u0440\u0435\u043d\u0442\u0443 (\u0434\u0438\u0432. \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447).
+ConfigView.section.file.perf.explain=\u041e\u0431\u0435\u0440\u0435\u0436\u043d\u043e - \u043d\u0435\u043e\u0431\u0434\u0443\u043c\u0430\u043d\u0456 \u0437\u043c\u0456\u043d\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0456\u0432 \u043c\u043e\u0436\u0443\u0442\u044c \u043c\u0430\u0442\u0438 \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u0438\u0439 \u0435\u0444\u0435\u043a\u0442 \u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.\n\u0412\u0438\u043c\u0430\u0433\u0430\u0454\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a. \u041f\u0440\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043d\u0456\u0439 \u043f\u0430\u043c'\u044f\u0442\u0456 \u043f\u043e\u0434\u0443\u043c\u0430\u0439\u0442\u0435 \u043f\u0440\u043e \u0437\u043d\u0438\u0436\u0435\u043d\u043d\u044f \u043a\u0456\u043b\u044c\u043a\u043e\u0441\u0442\u0456 \u0437\u0432'\u044f\u0437\u043a\u0456\u0432 \u0442\u043e\u0440\u0435\u043d\u0442\u0443 (\u0434\u0438\u0432. \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447).
 ConfigView.section.file.max_open_files.explain=\u041f\u0440\u0438 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u0445 \u0432\u0435\u043b\u0438\u043a\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438\u0445 \u0444\u0430\u0439\u043b\u0456\u0432 \u043c\u043e\u0436\u0435 \u0441\u043f\u0440\u0438\u0447\u0438\u043d\u0438\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439\u043d\u043e\u0457 \u0441\u0438\u0441\u0442\u0435\u043c\u0438. \u0422\u0443\u0442 \u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0431\u043c\u0435\u0436\u0438\u0442\u0438 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043e\u0434\u043d\u043e\u0447\u0430\u0441\u043d\u043e \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438\u0445 \u0444\u0430\u0439\u043b\u0456\u0432.
 popup.error.hide=\u0421\u0445\u043e\u0432\u0430\u0442\u0438
-popup.error.details=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456
-ConfigView.section.style.colorOverrides=\u0417\u043c\u0456\u043d\u0430 \u043a\u043e\u043b\u044c\u043e\u0440\u0456\u0432
+popup.error.details=\u0414\u043e\u043a\u043b\u0430\u0434\u043d\u043e
+ConfigView.section.style.colorOverrides=\u041f\u0456\u0434\u043c\u0456\u043d\u0430 \u043a\u043e\u043b\u044c\u043e\u0440\u0456\u0432
 ConfigView.section.style.colorOverride.progressBar=\u0406\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u043d\u044f
 ConfigView.section.style.colorOverride.error=\u041f\u043e\u043c\u0438\u043b\u043a\u0430
 MainWindow.status.tooOld=\u0437\u0430\u0441\u0442\u0430\u0440\u0456\u043b\u0430, \u0431\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u043f\u043e\u043d\u043e\u0432\u0456\u0442\u044c.
 ConfigView.section.style.colorOverride.warning=\u0423\u0432\u0430\u0433\u0430
 ConfigView.section.style.colorOverride.altRow=\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u0438\u0439 \u0440\u044f\u0434\u043e\u043a
-ConfigView.section.file.save.peers.enable=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u0437\u0432'\u044f\u0437\u043e\u043a \u0437 \u0441\u0456\u0434\u0435\u0440\u0430\u043c\u0438 \u0434\u043b\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0433\u043e \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
+ConfigView.section.file.save.peers.enable=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u0437\u0432'\u044f\u0437\u043e\u043a \u0437 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c\u0438 \u0434\u043b\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0433\u043e \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
 ConfigView.section.file.save.peers.max=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0438\u0445 \u0437\u0432'\u044f\u0437\u043a\u0456\u0432 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0438\u0439]
-ConfigView.section.file.save.peers.pertorrent=\u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
+ConfigView.section.file.save.peers.pertorrent=\u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 ConfigView.label.max_peers_per_torrent=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437'\u0454\u0434\u043d\u0430\u043d\u044c \u0434\u043b\u044f \u043a\u043e\u0436\u043d\u043e\u0433\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0443 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
 ConfigView.label.max_peers_total=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0432\u0441\u0456\u0445 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
 ConfigView.section.style.colorOverrides.reset=\u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438 \u043f\u043e\u0447\u0430\u0442\u043a\u043e\u0432\u0456 \u043a\u043e\u043b\u044c\u043e\u0440\u0438
-ConfigView.section.language.info=\u042f\u043a\u0449\u043e \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0430 \u0446\u044f \u043e\u043f\u0446\u0456\u044f, \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c \u0431\u0443\u0434\u0435 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043a\u043e\u0436\u043d\u043e\u043c\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438
+ConfigView.section.language.info=\u042f\u043a\u0449\u043e \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u0439 \u0446\u0435\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c \u0431\u0443\u0434\u0435 \u0432\u0456\u0434\u0431\u0443\u0432\u0430\u0442\u0438\u0441\u044f \u043f\u0440\u0438 \u043a\u043e\u0436\u043d\u043e\u043c\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438
 ConfigView.section.language.enableUpdate=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0440\u0435\u0436\u0443
 ConfigView.section.language.UpdateURL=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 URL
 ConfigView.section.language.UpdateNow=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u0437\u0430\u0440\u0430\u0437!
-Button.revert=\u041d\u0430\u0437\u0430\u0434
+Button.revert=\u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438
 MyTorrentsView.menu.changeDirectory=\u0417\u043c\u0456\u043d\u0438\u0442\u0438 \u0442\u0435\u043a\u0438 \u0434\u0430\u043d\u0438\u0445
 GenericText.column=\u0421\u0442\u043e\u0432\u043f\u0435\u0446\u044c
 MyTorrentsView.menu.thisColumn.remove=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0441\u0442\u043e\u0432\u043f\u0435\u0446\u044c
 MyTorrentsView.menu.thisColumn.toClipboard=\u0412 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0456\u043d\u0443
-MyTorrentsView.menu.thisColumn.autoTooltip=\u0417\u0430\u0432\u0436\u0434\u0438 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0441\u043f\u043b\u0438\u0432\u0430\u044e\u0447\u0435 \u0432\u0456\u043a\u043d\u043e
+MyTorrentsView.menu.thisColumn.autoTooltip=\u0417\u0430\u0432\u0436\u0434\u0438 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0432\u0438\u0440\u0438\u043d\u0430\u044e\u0447\u0435 \u0432\u0456\u043a\u043d\u043e
 MyTorrentsView.menu.tracker=\u0422\u0440\u0435\u043a\u0435\u0440
 ConfigView.download.abbreviated=\u0417\u0430\u0432\u0430\u043d\u0442.:
 ConfigView.upload.abbreviated=\u0420\u043e\u0437\u0434.:
-ConfigView.complete.abbreviated=\u041e\u041a:
+ConfigView.complete.abbreviated=\u0413\u0430\u0440\u0430\u0437\u0434:
 TableColumn.header.secondsseeding=\u0420\u043e\u0437\u0434\u0430\u0454\u043c\u043e \u0432\u0436\u0435
 TableColumn.header.secondsseeding.info=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0438\u0439 \u0447\u0430\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 TableColumn.header.secondsdownloading=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0454\u043c\u043e \u0432\u0436\u0435
 TableColumn.header.secondsdownloading.info=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0438\u0439 \u0447\u0430\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 ConfigView.section.tracker.udpversion=\u0412\u0435\u0440\u0441\u0456\u044f \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 UDP (1 \u0430\u0431\u043e 2)
 window.updateswt.title=\u0412\u0430\u0448\u0430 \u0432\u0435\u0440\u0441\u0456\u044f \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438 SWT \u0437\u0430\u0441\u0442\u0430\u0440\u0456\u043b\u0430!
-window.updateswt.text=\u0412\u0430\u0448\u0430 \u0432\u0435\u0440\u0441\u0456\u044f \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438 SWT \u0437\u0430\u0441\u0442\u0430\u0440\u0456\u043b\u0430!\nVuze \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454 \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438 SWT \u0434\u043b\u044f \u0432\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0433\u0440\u0430\u0444\u0456\u043a\u0438. \u041e\u0441\u0442\u0430\u043d\u043d\u044f \u0432\u0435\u0440\u0441\u0456\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043d\u043e\u0432\u0456\u0448\u043e\u0457 \u0432\u0435\u0440\u0441\u0456\u0457 SWT.\n\u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u041e\u041a \u0434\u043b\u044f \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f SWT.
+window.updateswt.text=\u0412\u0430\u0448\u0430 \u0432\u0435\u0440\u0441\u0456\u044f \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438 SWT \u0437\u0430\u0441\u0442\u0430\u0440\u0456\u043b\u0430!\nVuze \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454 \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438 SWT \u0434\u043b\u044f \u0432\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0433\u0440\u0430\u0444\u0456\u043a\u0438. \u041e\u0441\u0442\u0430\u043d\u043d\u044f \u0432\u0435\u0440\u0441\u0456\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043d\u043e\u0432\u0456\u0448\u043e\u0457 \u0432\u0435\u0440\u0441\u0456\u0457 SWT.\n\u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u0413\u0430\u0440\u0430\u0437\u0434 \u0434\u043b\u044f \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f SWT.
 window.updateswt.status=\u0421\u0442\u0430\u0442\u0443\u0441
-window.updateswt.failed=\u041f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u043d\u0435 \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u0435, \u043d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u041e\u041a \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443.
+window.updateswt.failed=\u041f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u043d\u0435 \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u0435, \u043d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u0413\u0430\u0440\u0430\u0437\u0434 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443.
 window.updateswt.status.downloading.updater=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u043c\u043e\u0434\u0443\u043b\u044f \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c
 window.updateswt.status.finding=\u041f\u043e\u0448\u0443\u043a \u043e\u0441\u0442\u0430\u043d\u043d\u044c\u043e\u0457 \u0432\u0435\u0440\u0441\u0456\u0457 \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438 SWT
 window.updateswt.status.downloading=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u043e\u0441\u0442\u0430\u043d\u043d\u044c\u043e\u0457 \u0432\u0435\u0440\u0441\u0456\u0457 \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438 SWT
 window.updateswt.status.done=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a
-window.updateswt.ok=\u041e\u041a
+window.updateswt.ok=\u0413\u0430\u0440\u0430\u0437\u0434
 window.updateswt.cancel=\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438
 swt.updater.downloader.downloading=\u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0430 SWT \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0454\u0442\u044c\u0441\u044f
-swt.updater.urlsgetter.downloading=\u041e\u0434\u0435\u0440\u0436\u0430\u043d\u043d\u044f \u0441\u043f\u0438\u0441\u043a\u0443 \u043b\u044e\u0441\u0442\u0435\u0440\u043e\u043a 
+swt.updater.urlsgetter.downloading=\u041e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u0441\u043f\u0438\u0441\u043a\u0443 \u043b\u044e\u0441\u0442\u0435\u0440\u043e\u043a 
 swt.updater.urlsgetter.platform=\u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0430 SWT \u0434\u043b\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0438 : 
 window.updateswt.ignore=\u041f\u0440\u043e\u0456\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438
 ConfigView.section.style.useFancyTabs=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043e\u0441\u043e\u0431\u043b\u0438\u0432\u0438\u0439 \u0432\u0438\u0433\u043b\u044f\u0434 \u0437\u0430\u043a\u043b\u0430\u0434\u043e\u043a
@@ -1023,27 +1023,27 @@ splash.loadingTorrents=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u0
 MyTorrentsView.menu.thisColumn.sort=&\u0421\u043e\u0440\u0442\u0443\u0432\u0430\u0442\u0438
 Scrape.status.ok=\u0428\u043a\u0440\u044f\u0431\u0430\u043d\u043d\u044f \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u0435.
 Scrape.status.error=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u0448\u043a\u0440\u044f\u0431\u0430\u043d\u043d\u044f:
-Scrape.status.error.badURL=\u0417\u0430\u0434\u0430\u043d\u0438\u0439 URL \u043d\u0435 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454 \u0441\u043f\u0435\u0446\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u0457 \u0448\u043a\u0440\u044f\u0431\u0430\u043d\u044c.
+Scrape.status.error.badURL=\u0417\u0430\u0434\u0430\u043d\u0430 \u0430\u0434\u0440\u0435\u0441\u0430 \u043d\u0435 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454 \u0441\u043f\u0435\u0446\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u0457 \u0448\u043a\u0440\u044f\u0431\u0430\u043d\u044c.
 Scrape.status.error.nohash=\u0412\u0456\u0434\u0441\u0443\u0442\u043d\u0456\u0441\u0442\u044c \u0445\u0435\u0448\u0443 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u0456.
 Scrape.status.error.invalid=\u041f\u043e\u043c\u0438\u043b\u043a\u043e\u0432\u0430 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u044c.
 Scrape.status.nextScrapeAt=\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u0435 \u0448\u043a\u0440\u044f\u0431\u0430\u043d\u043d\u044f %1
 Scrape.status.scraping=\u0428\u043a\u0440\u044f\u0431\u0430\u043d\u043d\u044f..
 Scrape.status.initializing=\u041e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u043a\u0440\u044f\u0431\u0430\u043d\u043d\u044f...
 Scrape.status.scraping.queued=\u0428\u043a\u0440\u044f\u0431\u0430\u043d\u043d\u044f \u0432 \u0447\u0435\u0440\u0437\u0456...
-ConfigView.label.minSpeedForActiveSeeding=\u0413\u043e\u0442\u043e\u0432\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442 \u043d\u0435 \u0437\u0430\u0439\u043c\u0430\u0454 \u0441\u043b\u043e\u0442, \u044f\u043a\u0449\u043e \u0439\u043e\u0433\u043e \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u043d\u0438\u0436\u0447\u0435 \u043d\u0456\u0436
-ConfigView.section.stats.exportpeers=\u0415\u043a\u0441\u043f\u043e\u0440\u0442\u0443\u0432\u0430\u0442\u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u043f\u0440\u043e \u0440\u043e\u0437\u0434\u0430\u0447\u0443
-MainWindow.menu.view.irc.moved=IRC \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439 \u0432 \u044f\u043a\u043e\u0441\u0442\u0456 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u043d\u0430 http://azureus.sourceforge.net/plugin_list.php. \u042f\u043a\u0449\u043e \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0435 - \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0439\u0442\u0435 \u043c\u0435\u043d\u044e \u0406\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438 > \u041f\u043b\u0430\u0433\u0456\u043d\u0438 > IRC
-MyTrackerView.webui.contextmenu.copyurl=\u0421\u043a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 URL \u0442\u043e\u0440\u0435\u043d\u0442\u0443 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0456\u043d\u0443
+ConfigView.label.minSpeedForActiveSeeding=\u0417\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442 \u043d\u0435 \u0437\u0430\u0439\u043c\u0430\u0454 \u0441\u043b\u043e\u0442, \u044f\u043a\u0449\u043e \u0439\u043e\u0433\u043e \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u043d\u0438\u0436\u0447\u0435 \u043d\u0456\u0436
+ConfigView.section.stats.exportpeers=\u0415\u043a\u0441\u043f\u043e\u0440\u0442\u0443\u0432\u0430\u0442\u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u043f\u0440\u043e \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
+MainWindow.menu.view.irc.moved=IRC \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439 \u0432 \u044f\u043a\u043e\u0441\u0442\u0456 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u043d\u0430 http://azureus.sourceforge.net/plugin_list.php. \u042f\u043a\u0449\u043e \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0435 - \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0439\u0442\u0435 \u043c\u0435\u043d\u044e \u0421\u0435\u0440\u0432\u0456\u0441 > \u0414\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f > IRC
+MyTrackerView.webui.contextmenu.copyurl=\u0421\u043a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0430\u0434\u0440\u0435\u0441\u0443 \u0442\u043e\u0440\u0435\u043d\u0442\u0443 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0456\u043d\u0443
 ConfigView.section.file.torrent.ignorefiles=\u041f\u0440\u0438 \u0441\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0456\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438\n(\u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434 DS_Store;Thumbs.db)
 Torrent.create.progress.ignoringfile=\u0424\u0430\u0439\u043b \u0456\u0433\u043d\u043e\u0440\u0443\u0454\u0442\u044c\u0441\u044f
 ConfigView.section.style.useUnitsRateBits=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0431\u0456\u0442\u0438 \u0437\u0430\u043c\u0456\u0441\u0442\u044c \u0431\u0430\u0439\u0442\u0456\u0432 \u0434\u043b\u044f \u0432\u0438\u043c\u0456\u0440\u044e\u0432\u0430\u043d\u0438\u0445 \u0432 \u0431\u0430\u0439\u0442\u0430\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f\u0445 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 (\u041a\u0431\u0456\u0442/\u0441 > \u041a\u0456\u0431\u0456\u0442/\u0441 \u0456 \u0456\u043d.)
 ConfigView.section.interface.resetassoc=\u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438 \u0432 \u043f\u043e\u0447\u0430\u0442\u043a\u043e\u0432\u0438\u0439 \u0441\u0442\u0430\u043d \u0430\u0441\u043e\u0446\u0456\u0430\u0446\u0456\u0457\n\u0437 \u0440\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u043d\u044f\u043c\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432  (.torrent)
-ConfigView.section.interface.resetassocbutton=\u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438 \u0432 \u043f\u043e\u0447\u0430\u0442\u043a\u043e\u0432\u0438\u0439 \u0441\u0442\u0430\u043d
-ConfigView.section.interface.checkassoc=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0437\u0432'\u044f\u0437\u043a\u0456\u0432 \u0440\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u044c \u0437 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043e\u044e \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443
+ConfigView.section.interface.resetassocbutton=\u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438 \u0434\u043e \u043f\u043e\u0447\u0430\u0442\u043a\u043e\u0432\u043e\u0433\u043e \u0441\u0442\u0430\u043d\u0443
+ConfigView.section.interface.checkassoc=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u0440\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u044c, \u043f\u043e\u0432'\u044f\u0437\u0430\u043d\u0438\u0445 \u0437 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043e\u044e
 dialog.associations.title=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0430\u0441\u043e\u0446\u0456\u0430\u0446\u0456\u0439
 Button.yes=&\u0422\u0430\u043a
 Button.no=&\u041d\u0456
-ConfigView.label.seeding.autoStart0Peers=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u0432\u0441\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u044f\u043a\u0449\u043e \u043d\u0435\u043c\u0430\u0454 \u0441\u0456\u0434\u0435\u0440\u0456\u0432
+ConfigView.label.seeding.autoStart0Peers=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u0432\u0441\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u044f\u043a\u0449\u043e \u043d\u0435\u043c\u0430 \u0441\u0456\u0434\u0435\u0440\u0456\u0432
 ConfigView.label.seeding.autoStart0Peers.tooltip=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0440\u0438 \u0431\u0430\u0436\u0430\u043d\u043d\u0456, \u0449\u043e\u0431 \u0441\u0435\u0440\u0432\u0435\u0440 \u0437\u0430\u0432\u0436\u0434\u0438 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0432 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0431\u0435\u0437 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432.
 dialog.associations.prompt=Vuze \u043d\u0435 \u0454 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043e\u044e \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u0456\u0432 BitTorrent.\n\u0411\u0430\u0436\u0430\u0454\u0442\u0435 \u043f\u0440\u0438\u0432\u043b\u0430\u0441\u043d\u0438\u0442\u0438 Vuze \u0446\u0435\u0439 \u0441\u0442\u0430\u0442\u0443\u0441?
 dialog.associations.askagain=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443
@@ -1056,7 +1056,7 @@ plugins.basicview.log=\u0416\u0443\u0440\u043d\u0430\u043b:
 ConfigView.label.maxdownloadspeed=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f, \u041a\u0431\u0456\u0442/\u0441 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
 splash.loadingTorrent=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 splash.of=\u0437
-ConfigView.section.plugins.irc=IRC-\u043a\u0430\u043d\u0430\u043b
+ConfigView.section.plugins.irc=\u041a\u0430\u043d\u0430\u043b IRC
 UpdateWindow.title=\u041f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f Vuze
 UpdateWindow.header=\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0435 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f:
 UpdateWindow.columns.install=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438
@@ -1073,14 +1073,14 @@ UpdateWindow.status.done=\u0412\u0438\u043a\u043e\u043d\u0430\u043d\u0435
 UpdateWindow.status.failed=\u041d\u0435 \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u0435
 UpdateWindow.status.restartNeeded=\u0412\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443!
 ConfigView.pluginlist.broken=\u041f\u043e\u0448\u043a\u043e\u0434\u0436\u0435\u043d\u0438\u0439
-ConfigView.pluginlist.whereToPut=\u041f\u043e\u043c\u0456\u0441\u0442\u0456\u0442\u044c \u043e\u0431\u0440\u0430\u043d\u0435 \u0412\u0430\u043c\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0437 \u0432\u043b\u0430\u0441\u043d\u043e\u0457 \u0442\u0435\u043a\u0438 \u0432:
+ConfigView.pluginlist.whereToPut=\u041f\u043e\u043c\u0456\u0441\u0442\u0456\u0442\u044c \u0432\u0438\u0431\u0440\u0430\u043d\u0435 \u0412\u0430\u043c\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0437 \u0432\u043b\u0430\u0441\u043d\u043e\u0457 \u0442\u0435\u043a\u0438 \u0432:
 ConfigView.pluginlist.whereToPutOr=\u0414\u043b\u044f \u0440\u043e\u0437\u0434\u0430\u043d\u0438\u0445 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438:
 MainWindow.statusText.checking=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u043d\u043e\u0432\u043e\u0457 \u0432\u0435\u0440\u0441\u0456\u0457
 TableColumn.header.OnlyCDing4=\u041d\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 TableColumn.header.OnlyCDing4.info=\u0410\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u0438\u0439 \u0447\u0430\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0430, \u043d\u0435 \u0432\u0440\u0430\u0445\u043e\u0432\u0443\u044e\u0447\u0438 \u0447\u0430\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 ConfigView.section.style.alternateTablePainting=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0443 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0441\u0442\u043e\u0432\u043f\u0446\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0456 (\u043c\u043e\u0436\u0435 \u0432\u0438\u043c\u0430\u0433\u0430\u0442\u0438\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a)
 UpdateWindow.status.restartMaybeNeeded=\u041c\u043e\u0436\u043b\u0438\u0432\u043e, \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0438\u0439 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a. 
-ConfigView.pluginlist.shared=\u0440\u043e\u0437\u0434\u0430\u043d\u0438\u0445
+ConfigView.pluginlist.shared=\u0440\u043e\u0437\u0434\u0430\u043d\u0438\u0439
 PeersView.host=\u0406\u043c'\u044f \u0445\u043e\u0441\u0442\u0430
 PeersView.host.info=\u0406\u043c'\u044f \u043f\u0440\u0438\u0439\u043c\u0430\u044e\u0447\u043e\u0433\u043e \u0445\u043e\u0441\u0442\u0430, \u044f\u043a\u0449\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e (\u0432\u043f\u043b\u0438\u0432\u0430\u0454 \u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c)
 MainWindow.menu.help.whatsnew=\u0429\u043e \u043d\u043e\u0432\u043e\u0433\u043e
@@ -1089,11 +1089,11 @@ ConfigView.label.periodiccheck=\u041f\u0435\u0440\u0456\u043e\u0434\u0438\u0447\
 ConfigView.label.opendialog=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u0438 \u041c\u0430\u0439\u0441\u0442\u0435\u0440 \u041f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c \u043f\u0440\u0438 \u043d\u0430\u044f\u0432\u043d\u043e\u0441\u0442\u0456 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c
 MainWindow.updateavail=\u0406\u0441\u043d\u0443\u0454 \u043d\u043e\u0432\u0430 \u0432\u0435\u0440\u0441\u0456\u044f
 MainWindow.status.unofficialversion=Vuze-\u0431\u0435\u0442\u0430
-MainWindow.status.latestversionunchecked=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u043e\u0441\u0442\u0430\u043d\u043d\u044c\u043e\u0457 \u0432\u0435\u0440\u0441\u0456\u0457 \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u0430
+MainWindow.status.latestversionunchecked=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u043e\u0441\u0442\u0430\u043d\u043d\u044c\u043e\u0457 \u0432\u0435\u0440\u0441\u0456\u0457 \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0430
 GeneralView.label.updatein.stopped=\u0417\u0443\u043f\u0438\u043d\u043a\u0430
 StartStopRules.menu.viewDebug=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u043d\u0443\u0442\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0436\u0435\u043d\u043d\u044f
 ConfigView.section.style.doNotUseGB=\u041d\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0413\u0411\u0430\u0439\u0442 \u044f\u043a \u043e\u0434\u0438\u043d\u0438\u0446\u044e
-ConfigView.section.style.doNotUseGB.tooltip=\u042f\u043a\u0449\u043e \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0430 \u043e\u043f\u0446\u0456\u044f, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 \u0431\u0443\u0434\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u0438 (M\u0411\u0430\u0439\u0442), \u043d\u0430\u0432\u0456\u0442\u044c \u044f\u043a\u0449\u043e \u0440\u043e\u0437\u043c\u0456\u0440 \u043f\u0435\u0440\u0435\u0432\u0438\u0449\u0443\u0454 1024 \u041c\u0411\u0430\u0439\u0442
+ConfigView.section.style.doNotUseGB.tooltip=\u042f\u043a\u0449\u043e \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 \u0431\u0443\u0434\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u0438 (M\u0411\u0430\u0439\u0442), \u043d\u0430\u0432\u0456\u0442\u044c \u044f\u043a\u0449\u043e \u0440\u043e\u0437\u043c\u0456\u0440 \u043f\u0435\u0440\u0435\u0432\u0438\u0449\u0443\u0454 1024 \u041c\u0411\u0430\u0439\u0442
 MainWindow.menu.help.plugins=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f
 ConfigView.section.plugins.TrackerWeb=\u0422\u0440\u0435\u043a\u0435\u0440 \u043c\u0435\u0440\u0435\u0436\u0456
 ConfigView.section.tracker.enablecategories=\u0421\u043e\u0440\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437\u0430 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u044f\u043c\u0438
@@ -1114,8 +1114,8 @@ security.certcreate.ok=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438
 security.certcreate.cancel=\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438
 security.certcreate.createok=\u0421\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f \u0441\u0435\u0440\u0442\u0438\u0444\u0456\u043a\u0430\u0442\u0430 \u043f\u0440\u043e\u0439\u0448\u043b\u043e \u0443\u0441\u043f\u0456\u0448\u043d\u043e
 security.certcreate.createfail=\u0421\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f \u0441\u0435\u0440\u0442\u0438\u0444\u0456\u043a\u0430\u0442\u0430 \u043f\u0440\u043e\u0439\u0448\u043b\u043e \u043d\u0435 \u0443\u0441\u043f\u0456\u0448\u043d\u043e
-ConfigView.section.plugins.webui=\u0417\u043c\u0456\u043d\u0430 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u043c\u0435\u0440\u0435\u0436\u0456
-ConfigView.section.plugins.xml_http_if=XML/HTTP-\u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441
+ConfigView.section.plugins.webui=\u0417\u043c\u0456\u043d\u0435\u043d\u043d\u044f \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u043c\u0435\u0440\u0435\u0436\u0456
+ConfigView.section.plugins.xml_http_if=\u0406\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 XML/HTTP
 webui.passwordenable=\u0410\u043a\u0442\u0438\u0432\u0443\u0432\u0430\u0442\u0438 \u043f\u0430\u0440\u043e\u043b\u044c
 webui.user=\u0406\u043c'\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430
 webui.password=\u041f\u0430\u0440\u043e\u043b\u044c
@@ -1125,12 +1125,12 @@ webui.homepage=\u0414\u043e\u043c\u0430\u0448\u043d\u044f \u0441\u0442\u043e\u04
 webui.rootdir=\u0413\u043e\u043b\u043e\u0432\u043d\u0430 \u0442\u0435\u043a\u0430 *
 webui.rootres=\u0413\u043e\u043b\u043e\u0432\u043d\u0438\u0439 \u0440\u0435\u0441\u0443\u0440\u0441 *
 webui.mode=\u0420\u0435\u0436\u0438\u043c *
-webui.mode.info=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0438\u0439 \u0440\u0435\u0436\u0438\u043c\n\t"\u041f\u043e\u0432\u043d\u0438\u0439"\t= \u0432\u0441\u0456 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0457 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456 (\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0439 \u0440\u0435\u0436\u0438\u043c)\n\t"\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434"\t= \u0442\u0456\u043b\u044c\u043a\u0438 \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u0434 (\u043c\u043e\u0436\u043b\u0438\u0432\u0435 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u0435 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f)
+webui.mode.info=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0438\u0439 \u0440\u0435\u0436\u0438\u043c\n\t"\u041f\u043e\u0432\u043d\u0438\u0439"\t= \u0432\u0441\u0456 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0457 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456 (\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0439 \u0440\u0435\u0436\u0438\u043c)\n\t"\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434"\t= \u043b\u0438\u0448\u0435 \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u0434\u0430\u043d\u043d\u044f (\u043c\u043e\u0436\u043b\u0438\u0432\u0435 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u0435 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f)
 webui.access=\u0414\u043e\u0441\u0442\u0443\u043f *
-webui.access.info=\u0414\u043e\u0441\u0442\u0443\u043f \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438\n\t"\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u0438\u0439"\t= \u043b\u0438\u0448\u0435 \u0446\u0435\u0439 \u043a\u043e\u043c\u043f'\u044e\u0442\u0435\u0440 \u043c\u0430\u0454 \u0434\u043e\u0441\u0442\u0443\u043f\n\t"\u0412\u0441\u0456"\t= \u0434\u043e\u0441\u0442\u0443\u043f \u0431\u0435\u0437 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u044c (\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0439)\n\tIP\t= \u043d\u0430\u043f\u0440. 192.168.0.2\t\t \u0442\u0456\u043b\u044c\u043a\u0438 \u043e\u0434\u043d\u0430 IP-\u0430\u0434\u0440\u0435\u0441\u0430\n\tIP1-IP2\t= \u043d\u0430\u043f\u0440. 192.168.0.1-192.168.0.255\t\u0432\u0440\u0430\u0445\u043e\u0432\u0443\u044e\u0447\u0438 \u043c\u0435\u0436\u0456 \u0430\u0434\u0440\u0435\u0441\u0438
+webui.access.info=\u0414\u043e\u0441\u0442\u0443\u043f \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438\n\t"\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u0438\u0439"\t= \u043b\u0438\u0448\u0435 \u0446\u0435\u0439 \u043a\u043e\u043c\u043f'\u044e\u0442\u0435\u0440 \u043c\u0430\u0454 \u0434\u043e\u0441\u0442\u0443\u043f\n\t"\u0412\u0441\u0456"\t= \u0434\u043e\u0441\u0442\u0443\u043f \u0431\u0435\u0437 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u044c (\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0439)\n\tIP\t= \u043d\u0430\u043f\u0440. 192.168.0.2\t\t \u043b\u0438\u0448\u0435 \u043e\u0434\u043d\u0430 IP-\u0430\u0434\u0440\u0435\u0441\u0430\n\tIP1-IP2\t= \u043d\u0430\u043f\u0440. 192.168.0.1-192.168.0.255\t\u0432\u0440\u0430\u0445\u043e\u0432\u0443\u044e\u0447\u0438 \u043c\u0435\u0436\u0456 \u0430\u0434\u0440\u0435\u0441\u0438
 GeneralView.label.maxdownloadspeed=\u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 Security.keystore.corrupt=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u043a\u043b\u044e\u0447\u0430 '%1', \u0431\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0432\u0438\u043b\u0443\u0447\u0456\u0442\u044c \u0439\u043e\u0433\u043e \u0456 \u0441\u0442\u0432\u043e\u0440\u0456\u0442\u044c \u0447\u0438 \u0456\u043c\u043f\u043e\u0440\u0442\u0443\u0439\u0442\u0435 \u0441\u0435\u0440\u0442\u0438\u0444\u0456\u043a\u0430\u0442 \u043d\u0430\u043d\u043e\u0432\u043e
-Security.keystore.empty=\u041a\u043b\u044e\u0447 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 \u043d\u0435 \u0456\u0441\u043d\u0443\u0454. \u0421\u0442\u0432\u043e\u0440\u0456\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u0456\u0439\u043d\u043e \u043f\u0456\u0434\u043f\u0438\u0441\u0430\u043d\u0438\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0456\u043a\u0430\u0442 (\u0434\u0438\u0432. \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f > \u0411\u0435\u0437\u043f\u0435\u043a\u0430) \u0430\u0431\u043e \u0456\u043c\u043f\u043e\u0440\u0442\u0443\u0439\u0442\u0435 \u0456\u0441\u043d\u0443\u044e\u0447\u0438\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0456\u043a\u0430\u0442 \u0432 '%1'
+Security.keystore.empty=\u041a\u043b\u044e\u0447 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 \u043d\u0435 \u0456\u0441\u043d\u0443\u0454. \u0421\u0442\u0432\u043e\u0440\u0456\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u0456\u0439\u043d\u043e \u043f\u0456\u0434\u043f\u0438\u0441\u0430\u043d\u0438\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0456\u043a\u0430\u0442 (\u0434\u0438\u0432. \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f > \u0411\u0435\u0437\u043f\u0435\u043a\u0430) \u0430\u0431\u043e \u0456\u043c\u043f\u043e\u0440\u0442\u0443\u0439\u0442\u0435 \u043d\u0430\u044f\u0432\u043d\u0438\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0456\u043a\u0430\u0442 \u0432 '%1'
 webui.restart.info=* \u0417\u043c\u0456\u043d\u0438 \u0446\u0438\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0456\u0432 \u0434\u0456\u044f\u0442\u0438\u043c\u0443\u0442\u044c \u043f\u0456\u0441\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 GeneralView.label.maxdownloadspeed.tooltip=, \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
 upnp.enable=\u0410\u043a\u0442\u0438\u0432\u0443\u0432\u0430\u0442\u0438 UPn
@@ -1140,9 +1140,9 @@ upnp.mapping.tcptrackerport=TCP \u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043
 upnp.mapping.udptrackerport=UDP \u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
 upnp.alert.differenthost=UPn: \u041f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f '%1' \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u043e\u0432\u0430\u043d\u0435 '%2' - \u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0456\u043d\u0448\u0438\u0439 \u043f\u043e\u0440\u0442
 upnp.alert.mappingok=UPn: \u041f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f '%1' \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u0435
-upnp.alert.mappingfailed=UPn: \u041f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f '%1' \u043d\u0435 \u0432\u0434\u0430\u0454\u0442\u044c\u0441\u044f \u0432\u0438\u043a\u043e\u043d\u0430\u0442\u0438
+upnp.alert.mappingfailed=UPn: \u041f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f '%1' \u043d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u0432\u0438\u043a\u043e\u043d\u0430\u0442\u0438
 upnp.alertsuccess=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0432\u0434\u0430\u043b\u0456 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f
-upnp.alert.lostdevice=UPn: \u0417\u0430\u0433\u0443\u0431\u043b\u0435\u043d\u0435 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0437 \u0441\u0435\u0440\u0432\u0456\u0441\u043e\u043c '%1' \u043d\u0430 Upn-\u043f\u0440\u0438\u0441\u0442\u0440\u043e\u0457 '%2'
+upnp.alert.lostdevice=UPn: \u0412\u0442\u0440\u0430\u0447\u0435\u043d\u0435 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0437 \u0441\u0435\u0440\u0432\u0456\u0441\u043e\u043c '%1' \u043d\u0430 Upn-\u043f\u0440\u0438\u0441\u0442\u0440\u043e\u0457 '%2'
 upnp.grabports=\u0420\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0438\u0442\u0438 \u043f\u043e\u0440\u0442\u0438, \u043d\u0430\u0432\u0456\u0442\u044c \u044f\u043a\u0449\u043e \u0432\u043e\u043d\u0438 \u043d\u0430\u043b\u0435\u0436\u0430\u0442\u044c \u0456\u043d\u0448\u043e\u043c\u0443 \u043a\u043e\u043c\u043f'\u044e\u0442\u0435\u0440\u0443
 upnp.refresh.label=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u0440\u043e\u0437\u043f\u043e\u0434\u0456\u043b \u043f\u043e\u0440\u0442\u0456\u0432
 upnp.refresh.button=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438
@@ -1163,59 +1163,59 @@ Peers.column.UpRatio=\u0421\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u044
 Peers.column.UpRatio.info=\u0421\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 "\u041e\u0442\u0440\u0438\u043c\u0430\u043d\u0435 \u0432\u0456\u0434 \u0432\u0430\u0441/\u041e\u0442\u0440\u0438\u043c\u0430\u043d\u0435 \u0432\u0456\u0434 \u0456\u043d\u0448\u0438\u0445"
 upnp.releasemappings=\u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u043a\u0440\u0438\u0442\u0442\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438
 webui.upnpenable=\u0414\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u0438 UPn \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0443 *
-ConfigView.section.file.friendly.hashchecking=\u0414\u0440\u0443\u0436\u043d\u044f \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0445\u0435\u0448-\u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457
+ConfigView.section.file.friendly.hashchecking=\u0414\u0440\u0443\u0436\u043d\u044f \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0445\u0435\u0448\u0443
 ConfigView.section.file.friendly.hashchecking.tooltip=\u0422\u0440\u043e\u0445\u0438 \u043f\u043e\u0432\u0456\u043b\u044c\u043d\u0438\u0439, \u0430\u043b\u0435 \u0456\u0441\u0442\u043e\u0442\u043d\u043e \u0440\u043e\u0437\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0454 \u0426\u041f\u0423 \u0442\u0430 \u0447\u0430\u0441\u0442\u043a\u043e\u0432\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 \u0445\u0435\u0448\u0443.
 ConfigView.section.tracker.seedretention=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043a\u043b\u0456\u0454\u043d\u0442\u0456\u0432, \u044f\u043a\u0430 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0454\u0442\u044c\u0441\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u043e\u043c [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430] 
-ConfigView.section.tracker.seedretention.info=\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430: \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0435\u0443\u0442\u0440\u0438\u043c\u0430\u043d\u0438\u0445 \u043a\u043b\u0456\u0454\u043d\u0442\u0456\u0432 \u0431\u0443\u0434\u0435 \u0437\u0430\u0433\u0443\u0431\u043b\u0435\u043d\u043e\u044e
-ConfigView.section.tracker.port=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0439 \u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-ConfigView.section.tracker.sslport=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0439 SSL-\u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-ConfigView.section.tracker.publicenable.info=\u0426\u0435 \u0434\u043e\u0437\u0432\u043e\u043b\u044f\u0454 \u0456\u043d\u0448\u0438\u043c \u0441\u0442\u0432\u043e\u0440\u044e\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u0449\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0442\u044c \u0432\u0430\u0448 \u0442\u0440\u0435\u043a\u0435\u0440
+ConfigView.section.tracker.seedretention.info=\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430: \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0435\u0443\u0442\u0440\u0438\u043c\u0430\u043d\u0438\u0445 \u043a\u043b\u0456\u0454\u043d\u0442\u0456\u0432 \u0431\u0443\u0434\u0435 \u0432\u0442\u0440\u0430\u0447\u0435\u043d\u043e\u044e
+ConfigView.section.tracker.port=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u043e\u0440\u0442 HTTP \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+ConfigView.section.tracker.sslport=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0439 \u043f\u043e\u0440\u0442 SSL \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+ConfigView.section.tracker.publicenable.info=\u0426\u0435 \u0434\u043e\u0437\u0432\u043e\u043b\u044f\u0454 \u0456\u043d\u0448\u0438\u043c \u0441\u0442\u0432\u043e\u0440\u044e\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u0449\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0442\u044c \u0412\u0430\u0448 \u0442\u0440\u0435\u043a\u0435\u0440,\n\u0430\u043b\u0435 \u0431\u0435\u0437 \u0412\u0430\u0448\u043e\u0433\u043e \u043f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f
 Button.clear=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438
-MainWindow.IPs.tooltip={\u041e\u0441\u0442\u0430\u043d\u043d\u0454 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0441\u043f\u0438\u0441\u043a\u0443 \u0444\u0456\u043b\u044c\u0442\u0440\u0430\u0446\u0456\u0457} \u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c IPFilters \u0443 \u0441\u043f\u0438\u0441\u043a\u0443 - \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0431\u043b\u043e\u043a\u043e\u0432\u0430\u043d\u0438\u0445/\u0437\u0430\u0431\u0430\u043d\u0435\u043d\u0438\u0445/\u043d\u0435\u0432\u0434\u0430\u043b\u0438\u0445 IP \u0434\u043b\u044f \u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0457 \u0441\u0435\u0441\u0456\u0457.\n\u0414\u0432\u0456\u0447\u0456 \u043a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043b\u0456\u0432\u043e\u044e \u0434\u043b\u044f \u0434\u043e\u043a\u043b\u0430\u0434\u043d\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457.
+MainWindow.IPs.tooltip={\u041e\u0441\u0442\u0430\u043d\u043d\u0454 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0441\u043f\u0438\u0441\u043a\u0443 \u0444\u0456\u043b\u044c\u0442\u0440\u0430\u0446\u0456\u0457} \u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0432\u0456\u0434\u0444\u0456\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u0438\u0445 IP - \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0431\u043b\u043e\u043a\u043e\u0432\u0430\u043d\u0438\u0445/\u0437\u0430\u0431\u0430\u043d\u0435\u043d\u0438\u0445/\u043d\u0435\u0432\u0434\u0430\u043b\u0438\u0445 IP \u0434\u043b\u044f \u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0457 \u0441\u0435\u0441\u0456\u0457.\n\u0414\u0432\u0456\u0447\u0456 \u043a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043b\u0456\u0432\u043e\u044e \u0434\u043b\u044f \u0434\u043e\u043a\u043b\u0430\u0434\u043d\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457.
 ConfigView.section.ipfilter.list.banned=\u0431\u043b\u043e\u043a\u043e\u0432\u0430\u043d\u0456 \u0437\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0443 \u043f\u043e\u043c\u0438\u043b\u043a\u043e\u0432\u0438\u0445 \u0434\u0430\u043d\u0438\u0445
 ConfigView.section.ipfilter.list.baddata=\u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u0456 \u043f\u043e\u043c\u0438\u043b\u043a\u043e\u0432\u0456 \u0434\u0430\u043d\u0456: \u0432\u0438\u043f\u0430\u0434\u043a\u0456\u0432: 
 Button.reset=\u0421\u043a\u0438\u043d\u0443\u0442\u0438
 ConfigView.section.ipfilter.bannedinfo=\u0410\u0434\u0440\u0435\u0441\u0438 IP, \u0449\u043e \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043b\u0438 \u043f\u043e\u043c\u0438\u043b\u043a\u043e\u0432\u0456 \u0434\u0430\u043d\u0456 \u0456 \u0431\u043b\u043e\u043a\u043e\u0432\u0430\u043d\u0456
 ConfigView.section.ipfilter.blockedinfo=\u0410\u0434\u0440\u0435\u0441\u0438, \u0431\u043b\u043e\u043a\u043e\u0432\u0430\u043d\u0456 \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u0444\u0456\u043b\u044c\u0442\u0440\u0456\u0432 IP
 download.removerules.name=\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f
-download.removerules.unauthorised.info=\u041d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u0438\u043c\u0438 \u0454 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0432 \u0442\u043e\u043c\u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443, \u044f\u043a\u0449\u043e \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u044c \u043d\u0430 \u0437\u0430\u043f\u0438\u0442 \u043c\u0456\u0441\u0442\u0438\u0442\u044c \u0430\u0431\u043e "not authoris(z)ed" \u0430\u0431\u043e "unauthoris(z)ed" \u0432 "\u041f\u043e\u043c\u0438\u043b\u0446\u0456 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u0456"
+download.removerules.unauthorised.info=\u041d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u0438\u043c\u0438 \u0454 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0432 \u0442\u043e\u043c\u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443, \u044f\u043a\u0449\u043e \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u044c \u043d\u0430 \u0437\u0430\u043f\u0438\u0442 \u043c\u0456\u0441\u0442\u0438\u0442\u044c \u0432 "\u041f\u043e\u043c\u0438\u043b\u0446\u0456 \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u0456" \u0440\u044f\u0434\u043a\u0438 "not authoris(z)ed" \u0430\u0431\u043e "unauthoris(z)ed" 
 download.removerules.unauthorised=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0435 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u043d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
 download.removerules.unauthorised.seedingonly=\t\u041b\u0438\u0448\u0435 \u043f\u0440\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 download.removerules.removed.ok=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0435 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f '%1' \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432. \u0426\u0435 \u0432\u0456\u0434\u0431\u0443\u043b\u043e\u0441\u044f \u0437\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432.
-download.removerules.updatetorrents=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u044f\u043a\u0456 \u043f\u043e\u043d\u043e\u0432\u043b\u044e\u044e\u0442\u044c Vuze, \u044f\u043a\u0449\u043e \u0446\u0435 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u043e\u0442\u043e\u0447\u0435\u043d\u043d\u044e
+download.removerules.updatetorrents=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c Vuze, \u044f\u043a\u0449\u043e \u0446\u0435 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u043e\u0442\u043e\u0447\u0435\u043d\u043d\u044e
 ConfigView.label.defaultstarttorrentsstopped=\u0414\u043e\u0434\u0430\u0432\u0430\u0442\u0438 \u043d\u043e\u0432\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0431\u0435\u0437 \u0457\u0445\u043d\u044c\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0443
 ConfigView.section.server.enableudp=\u0410\u043a\u0442\u0438\u0432\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b UDP
 upnp.mapping.dataportudp=UDP-\u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
 ConfigView.section.file.decoder.showlax=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0433\u0456\u0440\u0448\u0456 \u043a\u043e\u0434\u0443\u0432\u0430\u043d\u043d\u044f
 ConfigView.section.file.decoder.showall=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0432\u0441\u0456 \u043c\u043e\u0436\u043b\u0438\u0432\u0456 \u043a\u043e\u0434\u0443\u0432\u0430\u043d\u043d\u044f
-MainWindow.status.updowndetails.tooltip=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u043f\u0440\u043e \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0430\u0431\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f - \u0434\u0432\u0456\u0447\u0456 \u043a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043f\u0440\u0430\u0432\u043e\u044e, \u0449\u043e\u0431 \u0437\u043c\u0456\u043d\u0438\u0442\u0438
+MainWindow.status.updowndetails.tooltip=\u0414\u043e\u043a\u043b\u0430\u0434\u043d\u043e \u043f\u0440\u043e \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0430\u0431\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f - \u0434\u0432\u0456\u0447\u0456 \u043a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043f\u0440\u0430\u0432\u043e\u044e, \u0449\u043e\u0431 \u0437\u043c\u0456\u043d\u0438\u0442\u0438
 TrackerClient.announce.warningmessage=\u0422\u0440\u0435\u043a\u0435\u0440 \u0434\u043b\u044f '%1' \u0432\u0438\u0434\u0430\u0432 \u043f\u043e\u043f\u0435\u0440\u0435\u0434\u0436\u0435\u043d\u043d\u044f '%2'
 ConfigView.section.tracker.natcheckenable=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u044f\u0442\u0438 \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c \u043f\u0440\u0438\u0439\u043e\u043c\u0443 \u0434\u0430\u043d\u0438\u0445 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0435\u043c \u0456 \u0432\u0438\u0434\u0430\u0432\u0430\u0442\u0438 \u043f\u043e\u043c\u0438\u043b\u043a\u0438, \u044f\u043a\u0449\u043e \u0446\u0435 \u043d\u0435 \u0432\u0434\u0430\u0454\u0442\u044c\u0441\u044f
-ConfigView.section.tracker.publishenabledetails=\u041f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u0456 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u0437 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
-ConfigView.section.tracker.publishenablepeerdetails=\u041f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u0442\u0438 \u0434\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u0443 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u043f\u0440\u043e \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430
+ConfigView.section.tracker.publishenabledetails=\u041f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u0442\u0438 \u0432\u0441\u0456 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u043f\u0440\u043e \u0442\u043e\u0440\u0435\u043d\u0442
+ConfigView.section.tracker.publishenablepeerdetails=\u041f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u0442\u0438 \u0432\u0441\u0456 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u043f\u0440\u043e \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430
 MyTrackerView.badnat=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430\u043b\u0430\u0448\u0442\u043e\u0432\u0430\u043d\u0438\u0439 NAT
 MyTrackerView.badnat.info=\u0421\u0456\u0434\u0435\u0440\u0438 \u0456 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0438, \u044f\u043a\u0456 \u043d\u0435 \u043f\u0440\u043e\u0439\u0448\u043b\u0438 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0443 NAT, \u044f\u043a\u0449\u043e \u0446\u0435 \u0434\u043e\u0437\u0432\u043e\u043b\u0435\u043d\u043e
 ConfigView.section.tracker.natchecktimeout=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0438\u0439 \u0447\u0430\u0441 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 (\u0441\u0435\u043a\u0443\u043d\u0434)
-ConfigView.section.file.perf.cache.enable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043a\u0435\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0434\u0438\u0441\u043a\u0430
+ConfigView.section.file.perf.cache.enable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043a\u0435\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0434\u0438\u0441\u043a\u0443
 ConfigView.section.file.perf.cache.size=\u0420\u043e\u0437\u043c\u0456\u0440 \u043a\u0435\u0448\u0443 \u0432 %1
 #Removed
 #MyTorrentsView.menu.setSpeed=Set Upload Speed
 MainWindow.menu.transfers=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 MainWindow.menu.transfers.startalltransfers=&\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u0432\u0441\u0456
-MainWindow.menu.transfers.stopalltransfers=&\u0417\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u0432\u0441\u0456
+MainWindow.menu.transfers.stopalltransfers=\u0417\u0443\u043f\u0438\u043d\u0438\u0442\u0438 &\u0432\u0441\u0456
 MainWindow.menu.transfers.pausetransfers=&\u041f\u0430\u0443\u0437\u0430
-MainWindow.menu.transfers.resumetransfers=&\u041e\u043d\u043e\u0432\u0438\u0442\u0438
-ConfigView.label.experimental.osx.kernel.panic.fix=\u0415\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0438\u0439 \u043f\u0430\u0442\u0447 \u0434\u043b\u044f \u0432\u0438\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f \u043f\u043e\u043c\u0438\u043b\u043a\u0438 kernel panics \u043d\u0430 \u0434\u0432\u043e\u043f\u0440\u043e\u0446\u0435\u0441\u043e\u0440\u043d\u0438\u0445 \u043c\u0430\u0448\u0438\u043d\u0430\u0445 \u0437 Mac OS X [\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443]
+MainWindow.menu.transfers.resumetransfers=&\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438
+ConfigView.label.experimental.osx.kernel.panic.fix=\u0415\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0430 \u043b\u0430\u0442\u043a\u0430 \u0434\u043b\u044f \u0432\u0438\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f \u043f\u043e\u043c\u0438\u043b\u043a\u0438 kernel panics \u043d\u0430 \u0434\u0432\u043e\u043f\u0440\u043e\u0446\u0435\u0441\u043e\u0440\u043d\u0438\u0445 \u043c\u0430\u0448\u0438\u043d\u0430\u0445 \u0437 Mac OS X [\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443]
 SystemTray.menu.pausetransfers=\u041f\u0440\u0438\u0437\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 SystemTray.menu.resumetransfers=\u041e\u043d\u043e\u0432\u0438\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 ConfigView.section.file.truncate.too.large=\u0420\u043e\u0437\u0440\u0456\u0437\u0430\u0442\u0438 \u043d\u0430\u0434\u0442\u043e \u0432\u0435\u043b\u0438\u043a\u0456 \u0444\u0430\u0439\u043b\u0438 \u043d\u0430 \u043c\u0435\u043d\u0448\u0456
-ConfigView.section.file.perf.cache.trace=\u0412\u0456\u0434\u0441\u043b\u0456\u0434\u043a\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0457 \u043a\u0435\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0437 \u043c\u0435\u0442\u043e\u044e \u0434\u0456\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0438
+ConfigView.section.file.perf.cache.trace=\u041f\u0440\u043e\u0441\u0442\u0435\u0436\u0443\u0432\u0430\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0457 \u043a\u0435\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0437 \u043c\u0435\u0442\u043e\u044e \u0434\u0456\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0438
 ConfigView.section.interface.enabletray=\u0412\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u0438 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u043c\u0443 \u0442\u0440\u0435\u0457 [\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443]
 PeerManager.status.error=\u041f\u043e\u043c\u0438\u043b\u043a\u0430
 Stats.title.full=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430
 TransferStatsView.title.full=\u041f\u0435\u0440\u0435\u0434\u0430\u043d\u043e
 CacheView.title.full=\u041a\u0435\u0448
-CacheView.general.size=\u041f\u043e\u0432\u043d\u0438\u0439 \u0440\u043e\u0437\u043c\u0456\u0440
+CacheView.general.size=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u043e\u0437\u043c\u0456\u0440
 CacheView.general.inUse=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f
 CacheView.general.title=\u0406\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u043f\u0440\u043e \u043a\u0435\u0448
 CacheView.reads.title=\u041e\u043f\u0435\u0440\u0430\u0446\u0456\u0457 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044f-\u0432\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044f: \u0437\u0447\u0438\u0442\u0443\u0432\u0430\u043d\u044c
@@ -1231,13 +1231,13 @@ CacheView.speeds.reads=\u0427\u0438\u0442\u0430\u043d\u043d\u044f
 CacheView.speeds.writes=\u0417\u0430\u043f\u0438\u0441
 CacheView.speeds.fromCache=\u0417 \u043a\u0435\u0448\u0443 \u0456 \u0432 \u043a\u0435\u0448
 CacheView.speeds.fromFile=\u0417 \u0444\u0430\u0439\u043b\u0443 \u0456 \u0432 \u0444\u0430\u0439\u043b
-CacheView.reads.amount=\u0412\u0441\u044c\u043e\u0433\u043e
+CacheView.reads.amount=\u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c
 CacheView.reads.avgsize=\u0421\u0435\u0440\u0435\u0434\u043d\u0456\u0439 \u0440\u043e\u0437\u043c\u0456\u0440
 openUrl.referrer=\u0410\u0434\u0440\u0435\u0441\u0430 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0438, \u044f\u043a\u0430 \u043f\u043e\u0441\u0438\u043b\u0430\u0454\u0442\u044c\u0441\u044f:
 openUrl.referrer.info=\u041f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u043b\u0438\u0448\u0435 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u0456\u0432, \u044f\u043a\u0456 \u043e\u0442\u0440\u0438\u043c\u0430\u043b\u0438 \u0457\u0457
-ConfigView.label.maxuploadspeedseeding=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u044f\u043a\u0449\u043e \u0412\u0438 \u0454 \u0454\u0434\u0438\u043d\u0438\u043c \u0441\u0456\u0434\u0435\u0440\u043e\u043c, K\u0411\u0430\u0439\u0442/\u0441 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
-ConfigView.label.transfer.ignorepeerports=\u0406\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0437 \u0446\u0438\u043c\u0438 \u043f\u043e\u0440\u0442\u0430\u043c\u0438 (\u0440\u043e\u0437\u0434\u0456\u043b\u044c\u043d\u0438\u043a - ';', \u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434 0;25)
-ConfigView.section.proxy.enable_socks.peer=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0440\u043e\u043a\u0441\u0456\u043c\u0430\u0446\u0456\u044e \u0434\u043b\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 (\u0442\u0456\u043b\u044c\u043a\u0438 \u0432\u0438\u0445\u0456\u0434\u043d\u0456 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f) [\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443]
+ConfigView.label.maxuploadspeedseeding=\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u043f\u0440\u0438 \u043b\u0438\u0448\u0435 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
+ConfigView.label.transfer.ignorepeerports=\u041d\u0435\u0445\u0442\u0443\u0432\u0430\u0442\u0438 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c\u0438 \u0437 \u0446\u0438\u043c\u0438 \u043f\u043e\u0440\u0442\u0430\u043c\u0438 (\u0440\u043e\u0437\u0434\u0456\u043b\u044f\u0442\u0438 ';', \u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434 0;25)
+ConfigView.section.proxy.enable_socks.peer=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0440\u043e\u043a\u0441\u0456\u043c\u0430\u0446\u0456\u044e \u0434\u043b\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 (\u043b\u0438\u0448\u0435 \u0432\u0438\u0445\u0456\u0434\u043d\u0456 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f) [\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443]
 ConfigView.section.proxy.peer.informtracker=\u0406\u043d\u0444\u043e\u0440\u043c\u0443\u0432\u0430\u0442\u0438 \u0442\u0440\u0435\u043a\u0435\u0440 \u043f\u0440\u043e \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f
 ConfigView.section.proxy.socks.version=\u0412\u0435\u0440\u0441\u0456\u044f SOCKS
 PiecesView.legend.written=\u0417\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0439
@@ -1247,49 +1247,49 @@ PiecesView.legend.incache=\u0414\u0430\u043d\u0438\u0445 \u0443 \u043a\u0435\u04
 PiecesView.typeItem.0=\u041f\u043e\u0432\u0456\u043b\u044c\u043d\u0438\u0439
 PiecesView.typeItem.1=\u0428\u0432\u0438\u0434\u043a\u0438\u0439
 PiecesView.type=\u0422\u0438\u043f
-Security.jar.tools_not_found=\u041f\u0456\u0434\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f JAR \u043d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f - \u0444\u0430\u0439\u043b 'tools.jar' \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u0438\u0439 \u0432 %1. \u0414\u0438\u0432\u0456\u0442\u044c\u0441\u044f \u0406\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438->\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f->\u0411\u0435\u0437\u043f\u0435\u043a\u0430 \u0434\u043b\u044f \u0434\u043e\u043a\u043b\u0430\u0434\u043d\u0456\u0448\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457.
+Security.jar.tools_not_found=\u041f\u0456\u0434\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f JAR \u043d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f - \u0444\u0430\u0439\u043b 'tools.jar' \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u0438\u0439 \u0432 %1. \u0414\u0438\u0432\u0456\u0442\u044c\u0441\u044f \u0421\u0435\u0440\u0432\u0456\u0441->\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f->\u0411\u0435\u0437\u043f\u0435\u043a\u0430 \u0434\u043b\u044f \u0434\u043e\u043a\u043b\u0430\u0434\u043d\u0456\u0448\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457.
 Security.jar.signfail=\u041f\u0456\u0434\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f JAR \u043d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f - %1
-ConfigView.section.security.toolsinfo=\u041f\u0456\u0434\u043f\u0438\u0441\u0430\u043d\u0456 JAR-\u0444\u0430\u0439\u043b\u0438 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0434\u0435\u044f\u043a\u0438\u0445 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c, \u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434, \u0434\u043b\u044f \u0417\u043c\u0456\u043d\u0438 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u043c\u0435\u0440\u0435\u0436\u0456 (\u043a\u043e\u043b\u0438 \u0432\u043e\u043d\u043e \u043d\u0430\u043b\u0430\u0448\u0442\u043e\u0432\u0430\u043d\u0435).\n\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0449\u043e\u0431 \u043f\u0456\u0434\u043f\u0438\u0441\u0430\u0442\u0438 JAR-\u0444\u0430\u0439\u043b, \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e \u043c\u0430\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u0434\u043e \u0444\u0430\u0439\u043b\u0443 'tools.jar', \u044f\u043a\u0438\u0439 \u0440\u043e\u0437\u043f\u043e\u0432\u0441\u044e\u0434\u0436\u0443\u0454\u0442\u044c\u0441\u044f \u0437 \u043f\u0430\u043a\u0435\u0442\u043e\u043c \u0440\u043e\u0437\u0440\u043e\u0431\u043a\u0438 Sun JDK (\u043d\u0435 \u043f\u043b\u0443\u0442\u0430\u0442\u0438 \u0437 JRE).\n\u042f\u043a\u0449\u043e \u0443 \u0432\u0430\u0441 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0442\u0456\u043b\u044c\u043a\u0438 JRE, \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0456\u0442\u044c \u0449\u0435 \u0456 JDK.\nVuze \u043f\u043e\u0432\u0438\u043d\u0435\u043d \u0437\u043d\u0430\u0439\u0442\u0438 \u0446\u0435\u0439 \u0444\u0430\u0439\u043b \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0456 \u0441\u0430\u043c\u043e\u0441\u0442\u0456\u0439\u043d\u043e. \u041e\u0434\u043d\u0430\u043a, \u044f\u043a\u0449\u043e \u0446\u0435 \u0439\u043e\u043c\u0443 \u043d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f, \u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0440\u0443\u0447\u043d\u0443 \u0432\u043a\u0430\u0437\u0430\u0442\u0438 \u0442\u0435\u043a\u0443, \u044f\u043a\u0430 \u043c\u0456\u0441\u0442\u0438\u0442\u044c \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0438\u0439 \u0444\u0430\u0439\u043b.
+ConfigView.section.security.toolsinfo=\u041f\u0456\u0434\u043f\u0438\u0441\u0430\u043d\u0456 JAR-\u0444\u0430\u0439\u043b\u0438 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0434\u0435\u044f\u043a\u0438\u0445 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c, \u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434, \u0434\u043b\u044f \u0417\u043c\u0456\u043d\u0438 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u043c\u0435\u0440\u0435\u0436\u0456 (\u043a\u043e\u043b\u0438 \u0432\u043e\u043d\u043e \u043d\u0430\u043b\u0430\u0448\u0442\u043e\u0432\u0430\u043d\u0435).\n\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0449\u043e\u0431 \u043f\u0456\u0434\u043f\u0438\u0441\u0430\u0442\u0438 JAR-\u0444\u0430\u0439\u043b, \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e \u043c\u0430\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u0434\u043e \u0444\u0430\u0439\u043b\u0443 'tools.jar', \u044f\u043a\u0438\u0439 \u043f\u043e\u0448\u0438\u0440\u044e\u0454\u0442\u044c\u0441\u044f \u0437 \u043f\u0430\u043a\u0435\u0442\u043e\u043c \u0440\u043e\u0437\u0440\u043e\u0431\u043a\u0438 Sun JDK (\u043d\u0435 \u043f\u043b\u0443\u0442\u0430\u0442\u0438 \u0437 JRE).\n\u042f\u043a\u0449\u043e \u0443 \u0432\u0430\u0441 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u043b\u0438\u0448\u0435 JRE, \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0456\u0442\u044c \u0449\u0435 \u0456 JDK.\nVuze \u043f\u043e\u0432\u0438\u043d\u0435\u043d \u0437\u043d\u0430\u0439\u0442\u0438 \u0446\u0435\u0439 \u0444\u0430\u0439\u043b \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0456 \u0441\u0430\u043c\u043e\u0441\u0442\u0456\u0439\u043d\u043e. \u041e\u0434\u043d\u0430\u043a, \u044f\u043a\u0449\u043e \u0446\u0435 \u0439\u043e\u043c\u0443 \u043d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f, \u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0440\u0443\u0447\u043d\u0443 \u0432\u043a\u0430\u0437\u0430\u0442\u0438 \u0442\u0435\u043a\u0443, \u044f\u043a\u0430 \u043c\u0456\u0441\u0442\u0438\u0442\u044c \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0438\u0439 \u0444\u0430\u0439\u043b.
 ConfigView.section.security.toolsdir=\u0422\u0435\u043a\u0430, \u044f\u043a\u0430 \u043c\u0456\u0441\u0442\u0438\u0442\u044c 'tools.jar'
 ConfigView.section.security.choosetoolssavedir=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u0442\u0435\u043a\u0443, \u044f\u043a\u0430 \u043c\u0456\u0441\u0442\u0438\u0442\u044c 'tools.jar'
 authenticator.torrent=\u0422\u043e\u0440\u0435\u043d\u0442
 ConfigView.section.proxy.peer.same=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0440\u043e\u043a\u0441\u0456 \u0456 \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0443, \u0456 \u0434\u043b\u044f \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0437 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c\u0438
 ConfigView.section.connection.network.max.simultaneous.connect.attempts=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043e\u0434\u043d\u043e\u0447\u0430\u043d\u0438\u0445 \u0432\u0438\u0445\u0456\u0434\u043d\u0438\u0445 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c
-ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0432\u0438\u0445\u0456\u0434\u043d\u0438\u0445 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c, \u044f\u043a\u0456 \u0432\u0438\u043a\u043e\u043d\u0443\u044e\u0442\u044c\u0441\u044f Vuze \u0432 \u0431\u0443\u0434\u044c-\u044f\u043a\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0447\u0430\u0441\u0443.\n\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430: Windows XP SP2 \u0441\u0430\u043c\u043e\u0441\u0442\u0456\u0439\u043d\u043e \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u0454 \u0432\u043d\u0443\u0442\u0440\u0456\u0448\u043d\u0454 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0435 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0432 10 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c.\u005cu0422\u0438\u043f\u043e\u0432\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f - 8. \u0417\u043d\u0430\u0447\u0435\u043d\u043d\u044f 0 \u043f\u043e\u0432\u043d\u0456\u0441\u0442\u044e \u0432\u0438\u043c\u0438\u043a\u0430\u0454 \u0432\u0438\u0445\u0456\u0434\u043d\u0438\u0439 \u0442\u0440\u0430\u0444\u0456\u043a.
-ConfigView.section.file.perf.cache.size.explain=\u041a\u0435\u0448 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0437\u043c\u0435\u043d\u0448\u0435\u043d\u043d\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439 \u0437\u0447\u0438\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0437 \u0434\u0438\u0441\u043a\u0430. \u0414\u043e\u043a\u0438 \u0412\u0438 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 java '-XX:MaxDirectMemorySize', \u0449\u043e\u0431 \u0432\u0440\u0443\u0447\u043d\u0443 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0443 \u043f\u0430\u043c'\u044f\u0442\u044c \u0434\u043b\u044f \u043a\u0435\u0448\u0443 \u0456 \u043c\u0435\u0440\u0435\u0436\u0435\u0432\u043e\u0433\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f, \u0412\u0438 \u043c\u0430\u0454\u0442\u0435 \u0437\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u0446\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043f\u0440\u0438\u043d\u0430\u0439\u043c\u043d\u0456 \u043d\u0430 %1 \u043d\u0438\u0436\u0447\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0432\u0430\u0448\u043e\u0457 \u0432\u0456\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0457 \u043c\u0430\u0448\u0438\u043d\u0438. \u041f\u043e\u0442\u043e\u0447\u043d\u0438\u0439 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u043e\u0437\u043c\u0456\u0440 \u0434\u043b\u044f \u0432\u0456\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0457 \u043c\u0430\u0448\u0438\u043d\u0438 %2. \u0414\u043b\u044f \u0456\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0456\u0439, \u044f\u043a \u0437\u043c\u0456\u043d\u044e\u0432\u0430\u0442\u0438 \u0446\u0435\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u0434\u0438\u0432. MemoryUsage \u043d\u0430 Wiki-\u0441\u0442\u043e\u0440\u0456\u043d\u0446\u0456: %3. \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u0446\u0438\u0445 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \u0441\u043f\u0440\u0438\u0447\u0438\u043d\u0438\u0442\u044c \u043f\u043e\u043c\u0438\u043b\u043a\u0443 '\u043d\u0430\u0434\u043b\u0438\u0448\u043a\u0443 \u043f\u0430\u043c'\u044f\u0442\u0456'. \u0414\u043e\u0441\u0442\u0430\u0442\u043d\u0456\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f\u043c \u0454 32 \u041c\u0411\u0430\u0439\u0442.
+ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0432\u0438\u0445\u0456\u0434\u043d\u0438\u0445 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c, \u044f\u043a\u0456 \u0432\u0438\u043a\u043e\u043d\u0443\u044e\u0442\u044c\u0441\u044f Vuze \u0432 \u0431\u0443\u0434\u044c-\u044f\u043a\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0447\u0430\u0441\u0443.\n\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430: Windows XP SP2 \u0441\u0430\u043c\u043e\u0441\u0442\u0456\u0439\u043d\u043e \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u0454 \u0432\u043d\u0443\u0442\u0440\u0456\u0448\u043d\u0454 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0435 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0432 10 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c. \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f - 8. \u0417\u043d\u0430\u0447\u0435\u043d\u043d\u044f 0 \u043f\u043e\u0432\u043d\u0456\u0441\u0442\u044e \u0432\u0438\u043c\u0438\u043a\u0430\u0454 \u0432\u0438\u0445\u0456\u0434\u043d\u0438\u0439 \u0442\u0440\u0430\u0444\u0456\u043a.
+ConfigView.section.file.perf.cache.size.explain=\u041a\u0435\u0448 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0437\u043c\u0435\u043d\u0448\u0435\u043d\u043d\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439 \u0437\u0447\u0438\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0437 \u0434\u0438\u0441\u043a\u0430. \u042f\u043a\u0449\u043e \u0412\u0438 \u043d\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 java '-XX:MaxDirectMemorySize', \u0449\u043e\u0431 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0443 \u043f\u0430\u043c'\u044f\u0442\u044c \u0434\u043b\u044f \u043a\u0435\u0448\u0443 \u0456 \u043c\u0435\u0440\u0435\u0436\u0435\u0432\u043e\u0433\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f, \u0412\u0438 \u043c\u0430\u0454\u0442\u0435 \u0437\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u0446\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043f\u0440\u0438\u043d\u0430\u0439\u043c\u043d\u0456 \u043d\u0430 %1 \u043d\u0438\u0436\u0447\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0432\u0430\u0448\u043e\u0457 \u0432\u0456\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0457 \u043c\u0430\u0448\u0438\u043d\u0438. \u041f\u043e\u0442\u043e\u0447\u043d\u0438\u0439 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u043e\u0437\u043c\u0456\u0440 \u0434\u043b\u044f \u0432\u0456\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0457 \u043c\u0430\u0448\u0438\u043d\u0438 %2. \u0414\u043b\u044f \u0456\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0456\u0439, \u044f\u043a \u0437\u043c\u0456\u043d\u044e\u0432\u0430\u0442\u0438 \u0446\u0435\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u0434\u0438\u0432. MemoryUsage \u043d\u0430 Wiki-\u0441\u0442\u043e\u0440\u0456\u043d\u0446\u0456: %3. \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u0446\u0438\u0445 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \u0441\u043f\u0440\u0438\u0447\u0438\u043d\u0438\u0442\u044c \u043f\u043e\u043c\u0438\u043b\u043a\u0443 '\u043d\u0430\u0434\u043b\u0438\u0448\u043a\u0443 \u043f\u0430\u043c'\u044f\u0442\u0456'. \u0414\u043e\u0441\u0442\u0430\u0442\u043d\u0456\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f\u043c \u0454 32 \u041c\u0411\u0430\u0439\u0442.
 MyTorrentsView.menu.setSpeed.unlimit=\u0411\u0435\u0437 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u044c
 MyTorrentsView.menu.setSpeed.unlimited=\u041d\u0435 \u043e\u0431\u043c\u0435\u0436\u0443\u0432\u0430\u0442\u0438
 MyTorrentsView.menu.setSpeed.disable=\u0417\u0430\u0431\u043e\u0440\u043e\u043d\u0438\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0443
-MyTorrentsView.menu.setSpeed.disabled=\u0412\u0438\u043c\u043a\u043d\u0435\u043d\u043e
+MyTorrentsView.menu.setSpeed.disabled=\u0412\u0438\u043c\u043a\u043d\u0443\u0442\u043e
 MyTorrentsView.menu.setSpeed.in=\u0432
 MyTorrentsView.menu.setSpeed.slots=\u0441\u043b\u043e\u0442\u0430\u0445
-GeneralView.label.maxuploadspeed=\u041c\u0430\u043a\u0441. \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456
+GeneralView.label.maxuploadspeed=\u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 GeneralView.label.maxuploadspeed.tooltip=, \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 [0 : \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
-MyTorrents.items.UpSpeedLimit.disabled=\u041d\u0435\u043c\u0430\u0454 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
+MyTorrents.items.UpSpeedLimit.disabled=\u041d\u0435\u043c\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 MyTorrents.items.UpSpeedLimit.unlimited=\u041d\u0435 \u043e\u0431\u043c\u0435\u0436\u0443\u0432\u0430\u0442\u0438
 TableColumn.header.maxupspeed=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 TableColumn.header.maxupspeed.info=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0434\u043b\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443
-ConfigView.section.file.perf.cache.enable.write=\u041a\u0435\u0448\u0443\u0432\u0430\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0434\u0430\u043d\u0456 \u0434\u043b\u044f \u0437\u043c\u0435\u043d\u0448\u0435\u043d\u043d\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439 \u0437\u0430\u043f\u0438\u0441\u0443 \u043d\u0430 \u0434\u0438\u0441\u043a, \u0430 \u0442\u0430\u043a\u043e\u0436 \u0437\u043c\u0435\u043d\u0448\u0443\u0432\u0430\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0457 \u0447\u0438\u0442\u0430\u043d\u043d\u044f \u0437 \u0434\u0438\u0441\u043a\u0443, \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0456 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u0438\u0445 \u0447\u0430\u0441\u0442\u0438\u043d
+ConfigView.section.file.perf.cache.enable.write=\u041a\u0435\u0448\u0443\u0432\u0430\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0434\u0430\u043d\u0456 \u0434\u043b\u044f \u0437\u043c\u0435\u043d\u0448\u0435\u043d\u043d\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439 \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0430 \u0434\u0438\u0441\u043a, \u0430 \u0442\u0430\u043a\u043e\u0436 \u0437\u043c\u0435\u043d\u0448\u0443\u0432\u0430\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0457 \u0447\u0438\u0442\u0430\u043d\u043d\u044f \u0437 \u0434\u0438\u0441\u043a\u0443, \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0456 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u0438\u0445 \u0447\u0430\u0441\u0442\u0438\u043d
 ConfigView.section.file.perf.cache.enable.read=\u0412\u0438\u043a\u043e\u043d\u0443\u0432\u0430\u0442\u0438 \u043f\u043e\u043f\u0435\u0440\u0435\u0434\u043d\u0454 \u0447\u0438\u0442\u0430\u043d\u043d\u044f \u0434\u043b\u044f \u0437\u043c\u0435\u043d\u0448\u0435\u043d\u043d\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439 \u0437\u0432\u0435\u0440\u0442\u0430\u043d\u044c \u0434\u043e \u0434\u0438\u0441\u043a\u0443 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 ConfigView.section.tracker.separatepeerids=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u0440\u0456\u0437\u043d\u0456 \u0456\u0434\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0442\u043e\u0440\u0438 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u0456 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0434\u0430\u043d\u0438\u0445
 ConfigView.section.tracker.separatepeerids.info=\u0417\u0431\u0456\u043b\u044c\u0448\u0443\u0454 \u0430\u043d\u043e\u043d\u0456\u043c\u043d\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0430\u0431\u043e \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \n\u043f\u0456\u0434 \u0447\u0430\u0441 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u043d\u0435 \u0430\u043d\u043e\u043d\u0456\u043c\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-ConfigView.section.interface.wavlocation=\u041c\u0456\u0441\u0446\u0435 \u0440\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443 *.wav
+ConfigView.section.interface.wavlocation=\u0420\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443 *.wav
 ConfigView.section.interface.wavlocation.info=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u0444\u0430\u0439\u043b * .wav \u0430\u0431\u043e \u0437\u0430\u043b\u0438\u0448\u0456\u0442\u044c \u043f\u043e\u0440\u043e\u0436\u043d\u0456\u043c \u0434\u043b\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u0437\u0432\u0443\u043a\u0443
 ConfigView.section.tracker.server=\u0421\u0435\u0440\u0432\u0435\u0440
 ConfigView.section.tracker.client=\u041a\u043b\u0456\u0454\u043d\u0442
 ConfigView.section.tracker.client.connecttimeout=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0438\u0439 \u0447\u0430\u0441 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f (\u0441\u0435\u043a\u0443\u043d\u0434)
 ConfigView.section.tracker.client.readtimeout=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0438\u0439 \u0447\u0430\u0441 \u0447\u0438\u0442\u0430\u043d\u043d\u044f (\u0441\u0435\u043a\u0443\u043d\u0434)
-MainWindow.menu.tools=&\u0406\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438
+MainWindow.menu.tools=&\u0421\u0435\u0440\u0432\u0456\u0441
 FilesView.path=\u0428\u043b\u044f\u0445
 FilesView.fullpath=\u0412\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u0438 \u043f\u043e\u0432\u043d\u0438\u0439 \u0448\u043b\u044f\u0445
 FilesView.remaining=\u0427\u0430\u0441\u0442\u0438\u043d\u0438, \u044f\u043a\u0456 \u0437\u0430\u043b\u0438\u0448\u0438\u043b\u0438\u0441\u044f
 TableColumn.header.trackername=\u041d\u0430\u0437\u0432\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0443
-TableColumn.header.trackername.info=\u041d\u0430\u0437\u0432\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0443, \u0437\u0430\u0434\u0430\u043d\u0430 URL
-ConfigView.group.override=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 \u043f\u0435\u0440\u0435\u043a\u0440\u0438\u0432\u0430\u043d\u043d\u044f
+TableColumn.header.trackername.info=\u041d\u0430\u0437\u0432\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0443, \u0437\u0430\u0434\u0430\u043d\u0430 \u0430\u0434\u0440\u0435\u0441\u043e\u044e
+ConfigView.group.override=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 \u043f\u0456\u0434\u043c\u0456\u043d\u0438
 ConfigView.section.file.perf.cache.notsmallerthan=\u041d\u0435 \u043a\u0435\u0448\u0443\u0432\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438, \u043c\u0435\u043d\u0448\u0456 \u043d\u0456\u0436 (\u0432 %1)
 PeersView.menu.blockupload=\u0411\u043b\u043e\u043a\u0443\u0432\u0430\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0443
 PeersView.menu.kickandban=\u0417\u0430\u0431\u0430\u043d\u0438\u0442\u0438
-PeersView.menu.kickandban.reason=\u0417\u0430\u0431\u043e\u0440\u043e\u043d\u044f\u0442\u0438 \u0440\u0443\u0447\u043d\u0435 \u043f\u0456\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044f
+PeersView.menu.kickandban.reason=\u0417\u0430\u0431\u043e\u0440\u043e\u043d\u044f\u0442\u0438 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0432\u0440\u0443\u0447\u043d\u0443
 PeersView.state=\u0421\u0442\u0430\u043d
 PeersView.state.info=\u0421\u0442\u0430\u043d \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
 PeersView.state.pending=\u041e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f
@@ -1298,25 +1298,25 @@ PeersView.state.handshake=\u041e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d
 PeersView.state.established=\u041f\u043e\u0432\u043d\u0456\u0441\u0442\u044e \u0437'\u0454\u0434\u043d\u0430\u043d\u0438\u0439
 ConfigView.section.tracker.processinglimits=\u041e\u0431\u0440\u043e\u0431\u043a\u0430 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u044c
 ConfigView.section.tracker.maxgettime=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u0447\u0430\u0441 \u043e\u0431\u0440\u043e\u0431\u043a\u0438 \u0437\u0430\u043f\u0438\u0442\u0443 GET (\u0441\u0435\u043a\u0443\u043d\u0434) [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0438\u0439]
-ConfigView.section.tracker.maxgettime.info=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0430\u043d\u043e\u043d\u0441\u0456\u0432 \u0456 \u0441\u0445\u043e\u0432\u0438\u0449
-ConfigView.section.tracker.maxposttimemultiplier=GET-\u043c\u043d\u043e\u0436\u043d\u0438\u043a \u0447\u0430\u0441\u0443 \u0434\u043b\u044f \u043e\u0431\u0440\u043e\u0431\u043a\u0438 \u0437\u0430\u043f\u0438\u0442\u0456\u0432 POST [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0438\u0439]
+ConfigView.section.tracker.maxgettime.info=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0430\u043d\u043e\u043d\u0441\u0456\u0432 \u0456 \u0437\u0430\u043f\u0438\u0442\u0456\u0432 \u0441\u0445\u043e\u0432\u0438\u0449
+ConfigView.section.tracker.maxposttimemultiplier=\u041c\u043d\u043e\u0436\u043d\u0438\u043a \u0447\u0430\u0441\u0443 \u0437\u0430\u043f\u0438\u0442\u0456\u0432 GET \u0434\u043b\u044f \u043e\u0431\u0440\u043e\u0431\u043a\u0438 \u0437\u0430\u043f\u0438\u0442\u0456\u0432 POST [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0438\u0439]
 ConfigView.section.tracker.maxposttimemultiplier.info=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043e\u0431\u0440\u043e\u0431\u043a\u0438 \u0444\u043e\u0440\u043c \u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440
 ConfigView.section.tracker.maxthreads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043e\u0434\u043d\u043e\u0447\u0430\u0441\u043d\u0438\u0445 \u0437\u0430\u043f\u0438\u0442\u0456\u0432
 DownloadManager.error.operationcancancelled=\u041e\u043f\u0435\u0440\u0430\u0446\u0456\u044f \u0441\u043a\u0430\u0441\u043e\u0432\u0430\u043d\u0430
 Torrent.create.progress.cancelled=\u041e\u043f\u0435\u0440\u0430\u0446\u0456\u044f \u0441\u043a\u0430\u0441\u043e\u0432\u0430\u043d\u0430
 sharing.progress.cancel=\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438
-wizard.maketorrents.autoopen=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f
-ConfigView.section.sharing.rescanenable=\u0414\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u0438 \u043f\u0435\u0440\u0456\u043e\u0434\u0438\u0447\u043d\u0435 \u0441\u043a\u0430\u043d\u0443\u0432\u0430\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447 \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u043f\u043e\u0448\u0443\u043a\u0443 \u0437\u043c\u0456\u043d
-ConfigView.section.sharing.rescanperiod=\u0406\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0441\u043a\u0430\u043d\u0443\u0432\u0430\u043d\u043d\u044f (\u0441\u0435\u043a\u0443\u043d\u0434)
+wizard.maketorrents.autoopen=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f
+ConfigView.section.sharing.rescanenable=\u0414\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u0438 \u043f\u0435\u0440\u0456\u043e\u0434\u0438\u0447\u043d\u0443 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0443 \u043a\u043b\u0430\u0441\u0438\u0447\u043d\u0438\u0445 \u0440\u043e\u0437\u0434\u0430\u0447 \u0449\u043e\u0434\u043e \u043c\u043e\u0436\u043b\u0438\u0432\u0438\u0445 \u0437\u043c\u0456\u043d
+ConfigView.section.sharing.rescanperiod=\u0427\u0430\u0441\u043e\u0432\u0438\u0439 \u043f\u0440\u043e\u043c\u0456\u0436\u043e\u043a \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0457 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 (\u0441\u0435\u043a\u0443\u043d\u0434)
 ConfigView.section.connection.advanced=\u0414\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u0456 \u043c\u0435\u0440\u0435\u0436\u0435\u0432\u0456 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f
 ConfigView.section.connection.advanced.mtu=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043e\u0434\u0438\u043d\u0438\u0446\u044f \u0432\u0438\u043c\u0456\u0440\u0443 \u043b\u0456\u043d\u0456\u0457 (MTU) 
-ConfigView.section.connection.advanced.mtu.tooltip=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u043e\u0437\u043c\u0456\u0440 \u043f\u0430\u043a\u0435\u0442\u0430, \u044f\u043a\u0438\u0439 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u0438\u0439 \u0432 \u043e\u0434\u043d\u043e\u043c\u0443 \u043a\u0430\u0434\u0440\u0456 \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0440\u0435\u0436\u0443.\nVuze \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454 MTU-40 (MSS) \u0434\u043b\u044f \u043f\u0430\u043a\u0435\u0442\u0456\u0432 \u043d\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0443.\n\u0411\u0430\u0436\u0430\u043d\u0456 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f:\n 576 - \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043c\u043d\u0438\u0445 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c\n1492 - \u0437'\u0454\u0434\u043d\u0430\u043d\u044c PPPo \n1500 - Ethernet, DSL \u0456 \u0448\u0438\u0440\u043e\u043a\u043e\u0433\u043e \u043a\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0456\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044f 
+ConfigView.section.connection.advanced.mtu.tooltip=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u043e\u0437\u043c\u0456\u0440 \u043f\u0430\u043a\u0435\u0442\u0430, \u044f\u043a\u0438\u0439 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u0438\u0439 \u0432 \u043e\u0434\u043d\u043e\u043c\u0443 \u043a\u0430\u0434\u0440\u0456 \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0440\u0435\u0436\u0443.\nVuze \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454 MTU-40 (MSS) \u0434\u043b\u044f \u043f\u0430\u043a\u0435\u0442\u0456\u0432 \u043d\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0443.\n\u0411\u0430\u0436\u0430\u043d\u0456 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f:\n 576 - \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043c\u043d\u0438\u0445 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c\n1492 - \u0437'\u0454\u0434\u043d\u0430\u043d\u044c PPPo \n1500 - Ethernet, DSL \u0456 \u0448\u0438\u0440\u043e\u043a\u043e\u0433\u043e \u043a\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f 
 ConfigView.section.connection.advanced.SO_RCVBUF=\u0420\u043e\u0437\u043c\u0456\u0440 \u0441\u043e\u043a\u0435\u0442\u0430 SO_RCVBUF [0: \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0432\u0430\u0448\u043e\u0457 \u041e\u0421]
-ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=\u041d\u0430\u043b\u0430\u0448\u0442\u043e\u0432\u0443\u0454 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f SO_RCVBUF (\u0432 \u0431\u0430\u0439\u0442\u0430\u0445), \u0442\u043e\u0431\u0442\u043e TCP \u043e\u0434\u0435\u0440\u0436\u0443\u0454 \u0440\u043e\u0437\u043c\u0456\u0440 \u0432\u0456\u043a\u043d\u0430.\nVuze \u0437\u0430\u043b\u0438\u0448\u0430\u0454 \u0446\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043d\u0435 \u043d\u0430\u043b\u0430\u0448\u0442\u043e\u0432\u0430\u043d\u0438\u043c, \u0449\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0454, \u0449\u043e \u0431\u0443\u0434\u0443\u0442\u044c \u0437\u0430\u0441\u0442\u043e\u0441\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u0441\u044f \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0430\u0448\u043e\u0457 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439\u043d\u043e\u0457 \u0441\u0438\u0441\u0442\u0435\u043c\u0438.\n\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430: Linux \u043f\u043e\u0434\u0432\u043e\u044e\u0454 \u0432\u043a\u0430\u0437\u0430\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f.
+ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=\u041d\u0430\u043b\u0430\u0448\u0442\u043e\u0432\u0443\u0454 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f SO_RCVBUF (\u0432 \u0431\u0430\u0439\u0442\u0430\u0445), \u0442\u043e\u0431\u0442\u043e TCP \u043e\u0442\u0440\u0438\u043c\u0443\u0454 \u0440\u043e\u0437\u043c\u0456\u0440 \u0432\u0456\u043a\u043d\u0430.\nVuze \u0437\u0430\u043b\u0438\u0448\u0430\u0454 \u0446\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043d\u0435 \u043d\u0430\u043b\u0430\u0448\u0442\u043e\u0432\u0430\u043d\u0438\u043c, \u0449\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0454, \u0449\u043e \u0431\u0443\u0434\u0443\u0442\u044c \u0437\u0430\u0441\u0442\u043e\u0441\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u0441\u044f \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0430\u0448\u043e\u0457 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439\u043d\u043e\u0457 \u0441\u0438\u0441\u0442\u0435\u043c\u0438.\n\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430: Linux \u043f\u043e\u0434\u0432\u043e\u044e\u0454 \u0432\u043a\u0430\u0437\u0430\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f.
 ConfigView.section.connection.advanced.SO_SNDBUF=\u0420\u043e\u0437\u043c\u0456\u0440 \u0441\u043e\u043a\u0435\u0442\u0430 SO_SNDBUF [0: \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0432\u0430\u0448\u043e\u0457 \u041e\u0421]
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=\u041d\u0430\u043b\u0430\u0448\u0442\u043e\u0432\u0443\u0454 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f SO_SNDBUF (\u0432 \u0431\u0430\u0439\u0442\u0430\u0445), \u0442\u043e\u0431\u0442\u043e TCP \u0432\u0456\u0434\u0441\u0438\u043b\u0430\u0454 \u0440\u043e\u0437\u043c\u0456\u0440 \u0432\u0456\u043a\u043d\u0430.\nVuze \u0437\u0430\u043b\u0438\u0448\u0430\u0454 \u0446\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043d\u0435 \u043d\u0430\u043b\u0430\u0448\u0442\u043e\u0432\u0430\u043d\u0438\u043c, \u0449\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0454, \u0449\u043e \u0431\u0443\u0434\u0443\u0442\u044c \u0437\u0430\u0441\u0442\u043e\u0441\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u0441\u044f \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0430\u0448\u043e\u0457 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439\u043d\u043e\u0457 \u0441\u0438\u0441\u0442\u0435\u043c\u0438.\n\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430: Linux \u043f\u043e\u0434\u0432\u043e\u044e\u0454 \u0432\u043a\u0430\u0437\u0430\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f.
 ConfigView.section.connection.advanced.IPDiffServ=\u041d\u0435\u0437\u0432\u0438\u0447\u043d\u0435 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043f\u0430\u043a\u0435\u0442\u0443, \u044f\u043a\u0438\u0439 \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u044f\u0454\u0442\u044c\u0441\u044f (\u043f\u043e\u043b\u0435 TOS)
-ConfigView.section.connection.advanced.IPDiffServ.tooltip=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u0454 \u043d\u0435\u0437\u0432\u0438\u0447\u043d\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0447\u0430\u0441\u0442\u0438\u043d\u0443 \u043f\u043e\u043b\u044f \u0442\u0438\u043f \u0441\u0435\u0440\u0432\u0456\u0441\u0443 (TOS) \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0443 IP \u043f\u0430\u043a\u0435\u0442\u0456\u0432, \u044f\u043a\u0456 \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u044c\u0441\u044f.\n\u0428\u0456\u0441\u0442\u043d\u0430\u0434\u0446\u044f\u0442\u0438\u0437\u043d\u0430\u0447\u043d\u0456 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043c\u043e\u0436\u0443\u0442\u044c \u0431\u0443\u0442\u0438 \u0432\u043a\u0430\u0437\u0430\u043d \u0437 \u043f\u0440\u0435\u0444\u0456\u043a\u0441\u043e\u043c '0x', \u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434  0x10.\nVuze \u0437\u0430\u043b\u0438\u0448\u0430\u0454 \u0446\u0456 \u0437\u043c\u0456\u0449\u0435\u043d\u043d\u044f, \u0432\u043a\u0430\u0437\u0443\u044e\u0447\u0438, \u0449\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0442\u044c\u0441\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0456 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0457 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439\u043d\u043e\u0457 \u0441\u0438\u0441\u0442\u0435\u043c\u0438.\n\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430: \u041e\u0441\u043d\u043e\u0432\u043d\u0456 \u043c\u0435\u0440\u0435\u0436\u0456 \u043c\u043e\u0436\u0443\u0442\u044c \u0437\u043d\u0435\u0445\u0442\u0443\u0432\u0430\u0442\u0438 \u0446\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f\u043c, \u0430\u043b\u0435 \u0446\u044f \u043e\u043f\u0446\u0456\u044f \u0432\u0430\u0436\u043b\u0438\u0432\u0430 \u0432 \u0437\u0430\u043b\u0435\u0436\u043d\u043e\u0441\u0442\u0456 \u0432\u0456\u0434 \u0432\u0435\u0440\u0441\u0456\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439\u043d\u043e\u0457 \u0441\u0438\u0441\u0442\u0435\u043c\u0438 \u0456 JRE.
+ConfigView.section.connection.advanced.IPDiffServ.tooltip=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u0454 \u043d\u0435\u0437\u0432\u0438\u0447\u043d\u0456\u0439 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0447\u0430\u0441\u0442\u0438\u043d\u0456 \u043f\u043e\u043b\u0435 \u0442\u0438\u043f\u0443 \u0441\u0435\u0440\u0432\u0456\u0441\u0443 (TOS) \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0443 IP \u043f\u0430\u043a\u0435\u0442\u0456\u0432, \u044f\u043a\u0456 \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u044c\u0441\u044f.\n\u0428\u0456\u0441\u0442\u043d\u0430\u0434\u0446\u044f\u0442\u0438\u0437\u043d\u0430\u0447\u043d\u0456 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043c\u043e\u0436\u0443\u0442\u044c \u0431\u0443\u0442\u0438 \u0432\u043a\u0430\u0437\u0430\u043d \u0437 \u043f\u0440\u0435\u0444\u0456\u043a\u0441\u043e\u043c '0x', \u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434  0x10.\nVuze \u0437\u0430\u043b\u0438\u0448\u0430\u0454 \u0446\u0456 \u0437\u043c\u0456\u0449\u0435\u043d\u043d\u044f, \u0432\u043a\u0430\u0437\u0443\u044e\u0447\u0438, \u0449\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0442\u044c\u0441\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0456 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0457 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439\u043d\u043e\u0457 \u0441\u0438\u0441\u0442\u0435\u043c\u0438.\n\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430: \u041e\u0441\u043d\u043e\u0432\u043d\u0456 \u043c\u0435\u0440\u0435\u0436\u0456 \u043c\u043e\u0436\u0443\u0442\u044c \u0437\u043d\u0435\u0445\u0442\u0443\u0432\u0430\u0442\u0438 \u0446\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f\u043c, \u0430\u043b\u0435 \u0446\u0435\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0432\u0430\u0436\u043b\u0438\u0432\u0438\u0439 \u0432 \u0437\u0430\u043b\u0435\u0436\u043d\u043e\u0441\u0442\u0456 \u0432\u0456\u0434 \u0432\u0435\u0440\u0441\u0456\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439\u043d\u043e\u0457 \u0441\u0438\u0441\u0442\u0435\u043c\u0438 \u0456 JRE.
 ConfigView.section.interface.confirm_torrent_removal=\u0417\u0430\u043f\u0438\u0442\u0443\u0432\u0430\u0442\u0438 \u043f\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0436\u0435\u043d\u043d\u044f \u043f\u0440\u0438 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 ConfigView.section.interface.confirm_torrent_removal.tooltip=\u0417\u0430\u043f\u0438\u0442\u0443\u0432\u0430\u0442\u0438 \u043f\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0436\u0435\u043d\u043d\u044f \u043f\u0440\u0438 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0443 \u0437 "\u041c\u043e\u0457 \u0442\u043e\u0440\u0435\u043d\u0442\u0438"
 MyTorrentsView.confirm_torrent_removal=\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438?\n
@@ -1324,34 +1324,34 @@ TableColumn.header.seed_to_peer_ratio=\u0421\u043f\u0456\u0432\u0432\u0456\u0434
 TableColumn.header.seed_to_peer_ratio.info=\u041f\u0456\u0434\u0441\u0443\u043c\u043a\u043e\u0432\u0435 \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f \u0441\u0456\u0434\u0435\u0440\u0456\u0432 \u0434\u043e \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432
 PeersView.connected_time=\u0427\u0430\u0441 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f
 PeersView.connected_time.info=\u041f\u0456\u0434\u0441\u0443\u043c\u043a\u043e\u0432\u0438\u0439 \u0447\u0430\u0441 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0437 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u043e\u043c
-ConfigView.section.interface.display.add_torrents_silently=\u0414\u043e\u0434\u0430\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0443 \u0444\u043e\u043d\u043e\u0432\u043e\u043c\u0443 \u0440\u0435\u0436\u0438\u043c\u0456
+ConfigView.section.interface.display.add_torrents_silently=\u0414\u043e\u0434\u0430\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u043d\u0430 \u0442\u043b\u0456
 ConfigView.section.interface.display.add_torrents_silently.tooltip=\u0414\u043e\u0434\u0430\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0432 \u0437\u0430\u0432\u0434\u0430\u043d\u043d\u044f \u0431\u0435\u0437 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0456\u0457 \u0433\u043e\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u0432\u0456\u043a\u043d\u0430 Vuze.
 TableColumn.header.maxdownspeed=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 TableColumn.header.maxdownspeed.info=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0446\u044c\u043e\u0433\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 PeersGraphicView.title=\u041e\u0442\u043e\u0447\u0435\u043d\u043d\u044f
-ConfigView.section.tracker.passwordwebhttpsonly=\u0414\u043e\u0437\u0432\u043e\u043b\u044f\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u0442\u0456\u043b\u044c\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u0445\u0438\u0449\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b HTTPS
-TableColumn.header.torrentpath=\u041c\u0456\u0441\u0446\u0435 \u0440\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
-TableColumn.header.torrentpath.info=\u041c\u0456\u0441\u0446\u0435 \u0440\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443 \u043d\u0430 \u0434\u0438\u0441\u043a\u0443
-ConfigView.section.sharing.torrentcomment=\u041a\u043e\u043c\u0435\u043d\u0442\u0430\u0440\u0456 \u0434\u043b\u044f \u0441\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
+ConfigView.section.tracker.passwordwebhttpsonly=\u0414\u043e\u0437\u0432\u043e\u043b\u044f\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043b\u0438\u0448\u0435 \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u0445\u0438\u0449\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b HTTPS
+TableColumn.header.torrentpath=\u0420\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
+TableColumn.header.torrentpath.info=\u0420\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443 \u043d\u0430 \u0434\u0438\u0441\u043a\u0443
+ConfigView.section.sharing.torrentcomment=\u041a\u043e\u043c\u0435\u043d\u0442\u0430\u0440 \u0434\u043b\u044f \u0441\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
 ConfigView.label.copyanddeleteratherthanmove=\u0421\u043a\u043e\u043f\u0456\u044e\u0439\u0442\u0435, \u0430 \u043f\u043e\u0442\u0456\u043c \u0432\u0438\u043b\u0443\u0447\u0456\u0442\u044c \u0434\u0430\u043d\u0456 \u0437\u0430\u043c\u0456\u0441\u0442\u044c \u0442\u043e\u0433\u043e, \u0449\u043e\u0431 \u043f\u0435\u0440\u0435\u043c\u0456\u0449\u0443\u0432\u0430\u0442\u0438 \u0437\u0430 \u043e\u0434\u043d\u0443 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u044e - \u0446\u0435 \u0434\u043e\u043f\u043e\u043c\u043e\u0436\u0435 \u0437\u0430\u043f\u043e\u0431\u0456\u0433\u0442\u0438 \u0432\u0442\u0440\u0430\u0442\u0456 \u0434\u0430\u043d\u0438\u0445 \u0443 \u0434\u0435\u044f\u043a\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432\u0438\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445
 ConfigView.label.openstatsonstart=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443
 swt.install.window.title=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f Vuze
 swt.install.window.ok=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438
-swt.install.window.header=\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u0456 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0438 \u043e\u0431\u0440\u0430\u043d\u0456 \u0434\u043b\u044f \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f:
+swt.install.window.header=\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u0456 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043d\u0456 \u0434\u043b\u044f \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f:
 swt.uninstall.window.title=\u0412\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c Vuze
 swt.uninstall.window.ok=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438
-swt.uninstall.window.header=\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u0456 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0438 \u043e\u0431\u0440\u0430\u043d\u0456 \u0434\u043b\u044f \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f :
+swt.uninstall.window.header=\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u0456 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043d\u0456 \u0434\u043b\u044f \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f :
 installPluginsWizard.title=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c
 installPluginsWizard.mode.title=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0441\u043f\u043e\u0441\u0456\u0431 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
-installPluginsWizard.mode.list=\u041e\u0442\u0440\u0438\u043c\u0430\u0442\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c \u0437 \u0441\u0430\u0439\u0442\u0443 sourceforge.net (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u0442\u044c\u0441\u044f)
+installPluginsWizard.mode.list=\u0417 \u0441\u043f\u0438\u0441\u043a\u0443 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c \u0441\u0430\u0439\u0442\u0443 sourceforge.net
 installPluginsWizard.list.title=\u0421\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c, \u0433\u043e\u0442\u043e\u0432\u0438\u0445 \u0434\u043e \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
-installPluginsWizard.list.loading=\u0417\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435, \u0434\u043e\u043a\u0438 \u043f\u043e\u043d\u043e\u0432\u043b\u044e\u0454\u0442\u044c\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c.
+installPluginsWizard.list.loading=\u0417\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435, \u043f\u043e\u043a\u0438 \u043f\u043e\u043d\u043e\u0432\u043b\u044e\u0454\u0442\u044c\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c.
 installPluginsWizard.list.loaded=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f, \u044f\u043a\u0435 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438.
 installPluginsWizard.list.name=\u041d\u0430\u0437\u0432\u0430
 installPluginsWizard.list.version=\u0412\u0435\u0440\u0441\u0456\u044f
 installPluginsWizard.list.description=\u041e\u043f\u0438\u0441 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f
 installPluginsWizard.finish.title=\u0422\u0440\u0438\u0432\u0430\u0454 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
-installPluginsWizard.finish.explanation=\u041e\u0431\u0440\u0430\u043d\u0456 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0431\u0443\u0434\u0443\u0442\u044c \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0456 \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u041c\u0430\u0439\u0441\u0442\u0440\u0430 \u041f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c\n\n\u0417\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435, \u0434\u043e\u043a\u0438 \u0432\u0456\u043d \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u044c\u0441\u044f\n\n\u0414\u043b\u044f \u0432\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0456\u043d\u0441\u0442\u0430\u043b\u044f\u0446\u0456\u0457, \u0434\u0432\u0456\u0447\u0456 \u043a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043b\u0456\u0432\u043e\u044e \u043f\u043e\n\u043f\u0430\u043d\u0435\u043b\u0456 \u0441\u0442\u0430\u043d\u0443.
+installPluginsWizard.finish.explanation=\u0412\u0438\u0431\u0440\u0430\u043d\u0456 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0431\u0443\u0434\u0443\u0442\u044c \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0456 \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u041c\u0430\u0439\u0441\u0442\u0440\u0430 \u041f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c\n\n\u0417\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435, \u043f\u043e\u043a\u0438 \u0432\u0456\u043d \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u044c\u0441\u044f\n\n\u0414\u043b\u044f \u0432\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0456\u043d\u0441\u0442\u0430\u043b\u044f\u0446\u0456\u0457, \u0434\u0432\u0456\u0447\u0456 \u043a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043b\u0456\u0432\u043e\u044e \u043f\u043e\n\u0440\u044f\u0434\u043a\u0443 \u0441\u0442\u0430\u043d\u0443.
 installPluginsWizard.details.loading=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u044e\u0442\u044c\u0441\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456, \u0431\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0437\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435...
 installPluginsWizard.mode.file=\u0412 \u0432\u0430\u0441 \u0432\u0436\u0435 \u0454 \u0444\u0430\u0439\u043b \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f
 installPluginsWizard.installMode.title=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0441\u043f\u043e\u0441\u0456\u0431 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
@@ -1390,22 +1390,22 @@ deletetorrent.message2=\n\u0412\u0438 \u0434\u0456\u0439\u0441\u043d\u043e \u044
 ConfigView.label.prioritizemostcompletedfiles=\u041f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0432 \u0437\u0430\u043b\u0435\u0436\u043d\u043e\u0441\u0442\u0456 \u0432\u0456\u0434 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443 (\u0432 % \u0430\u0431\u043e \u0432\u0456\u0434 \u0440\u043e\u0437\u043c\u0456\u0440\u0443)
 splash.plugin.init=\u0417\u0430\u043f\u0443\u0441\u043a \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f:
 splash.plugin.UIinit=\u0406\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u044f \u0432\u0438\u0433\u043b\u044f\u0434\u0443 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f: %1  
-ConfigView.section.style.osx_small_fonts=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u0456 \u0448\u0440\u0438\u0444\u0442\u0438 [\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443]
+ConfigView.section.style.osx_small_fonts=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0434\u0440\u0456\u0431\u043d\u0456 \u0448\u0440\u0438\u0444\u0442\u0438 [\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443]
 ConfigView.section.tracker.tcpnonblocking=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044f-\u0432\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044f, \u044f\u043a\u0435 \u043d\u0435 \u0431\u043b\u043e\u043a\u0443\u0454\u0442\u044c\u0441\u044f, \u0434\u043b\u044f \u0440\u043e\u0431\u043e\u0442\u0438 TCP-\u0442\u0440\u0435\u043a\u0435\u0440\u0443. \u0412\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u0446\u044c\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0432\u0438\u043c\u0430\u0433\u0430\u0454, \u0449\u043e\u0431 \u0442\u0440\u0435\u043a\u0435\u0440-\u0441\u0430\u0439\u0442 \u0431\u0443\u0432 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0438\u0439 \u0447\u0435\u0440\u0435\u0437 \u0456\u043d\u0448\u0438\u0439 \u043f\u043e\u0440\u0442. \u0415\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0430 \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c!
 ConfigView.section.tracker.nonblocking=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438, \u044f\u043a\u0456 \u043d\u0435 \u0431\u043b\u043e\u043a\u0443\u044e\u0442\u044c\u0441\u044f
 ConfigView.section.tracker.nonblockingconcmax=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043e\u0434\u043d\u043e\u0447\u0430\u0441\u043d\u0438\u0445 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
 MyTorrentsView.menu.exportmenu=\u0415\u043a\u0441\u043f\u043e\u0440\u0442
 MyTorrentsView.menu.exporttorrent=\u0422\u043e\u0440\u0435\u043d\u0442...
 ConfigView.group.scrape=\u0421\u0445\u043e\u0432\u0438\u0449\u0435
-ConfigView.section.tracker.client.scrapeinfo=\u0412\u0438\u043c\u0438\u043a\u0430\u043d\u043d\u044f \u0441\u0445\u043e\u0432\u0438\u0449\u0430 \u0441\u043f\u0440\u0438\u0447\u0438\u043d\u0438\u0442\u044c \u0432\u0456\u0434\u043c\u043e\u0432\u0443 \u043f\u0440\u0430\u0446\u044e\u0432\u0430\u0442\u0438 \u0431\u0430\u0433\u0430\u0442\u044c\u043e\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u043e\u0431\u0441\u043b\u0443\u0433\u043e\u0432\u0443\u0432\u0430\u043d\u043d\u044f \u0447\u0435\u0440\u0433\u0438, \u0442\u043e\u043c\u0443 \u0449\u043e \u0432\u043e\u043d\u0438 \u043f\u043e\u043a\u043b\u0430\u0434\u0430\u044e\u0442\u044c\u0441\u044f \u043d\u0430 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u043f\u0440\u043e \u043e\u0442\u043e\u0447\u0435\u043d\u043d\u044f, \u044f\u043a\u0430 \u0437\u0431\u0435\u0440\u0456\u0433\u0454\u0442\u044c\u0441\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438-\u0441\u0445\u043e\u0432\u0438\u0449\u0430\u043c\u0438.
+ConfigView.section.tracker.client.scrapeinfo=\u0412\u0438\u043c\u0438\u043a\u0430\u043d\u043d\u044f \u0441\u0445\u043e\u0432\u0438\u0449\u0430 \u0441\u043f\u0440\u0438\u0447\u0438\u043d\u0438\u0442\u044c \u0432\u0456\u0434\u043c\u043e\u0432\u0443 \u0431\u0430\u0433\u0430\u0442\u044c\u043e\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u043e\u0431\u0441\u043b\u0443\u0433\u043e\u0432\u0443\u0432\u0430\u043d\u043d\u044f \u0447\u0435\u0440\u0433\u0438, \u0442\u043e\u043c\u0443 \u0449\u043e \u0432\u043e\u043d\u0438 \u043f\u043e\u043a\u043b\u0430\u0434\u0430\u044e\u0442\u044c\u0441\u044f \u043d\u0430 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u043f\u0440\u043e \u043e\u0442\u043e\u0447\u0435\u043d\u043d\u044f, \u044f\u043a\u0430 \u0437\u0431\u0435\u0440\u0456\u0433\u0430\u0454\u0442\u044c\u0441\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438-\u0441\u0445\u043e\u0432\u0438\u0449\u0430\u043c\u0438.
 ConfigView.section.tracker.client.scrapeenable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0441\u0445\u043e\u0432\u0438\u0449\u0435
 ConfigView.section.tracker.client.scrapestoppedenable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0441\u0445\u043e\u0432\u0438\u0449\u0435 \u0434\u043b\u044f \u043d\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
-Scrape.status.disabled=\u0421\u0445\u043e\u0432\u0438\u0449\u0435 \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u0435
+Scrape.status.disabled=\u0421\u0445\u043e\u0432\u0438\u0449\u0435 \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0435
 MyTorrentsView.menu.explore=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0444\u0430\u0439\u043b
-MyTorrentsView.menu.explore._mac=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0432 Finder
+MyTorrentsView.menu.explore._mac=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0432 \u043f\u043e\u0448\u0443\u043a\u0443
 MyTorrentsView.menu.explore._windows=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0432 \u043f\u0440\u043e\u0432\u0456\u0434\u043d\u0438\u043a\u0443 Windows
 wizard.maketorrents.autohost=\u041d\u0430\u0434\u0430\u0442\u0438 \u0445\u043e\u0441\u0442 \u0442\u043e\u0440\u0435\u043d\u0442\u0443 \u043d\u0430 \u0432\u0431\u0443\u0434\u043e\u0432\u0430\u043d\u043e\u043c\u0443 \u0442\u0440\u0435\u043a\u0435\u0440\u0456
-ConfigView.label.overrideip=IP-\u0430\u0434\u0440\u0435\u0441\u0430, \u044f\u043a\u0430 \u043d\u0430\u0434\u0441\u0438\u043b\u0430\u0454\u0442\u044c\u0441\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0443 (NAT)
+ConfigView.label.overrideip=\u041f\u0456\u0434\u043c\u0456\u043d\u0438\u0442\u0438 \u0430\u043d\u043e\u043d\u0441\u043e\u0432\u0430\u043d\u0438\u0439 IP \u0442\u0440\u0435\u043a\u0435\u0440\u0430. \u0420\u043e\u0437\u0434\u0456\u043b\u044f\u0442\u0438 \u043a\u043e\u043c\u0430\u043c\u0438 \u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443, \u044f\u043a\u0449\u043e \u0457\u0445 \u043a\u0456\u043b\u044c\u043a\u0430 \u0434\u043b\u044f \u0440\u0456\u0437\u043d\u0438\u0445 \u043c\u0435\u0440\u0435\u0436
 ConfigView.label.overrideip.tooltip=\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u044f\u0442\u0438 \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u043f\u0440\u043e \u0440\u0456\u0437\u043d\u0456 IP-\u0430\u0434\u0440\u0435\u0441\u0438, \u0432\u0456\u0434 \u044f\u043a\u0438\u0445 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442\u044c \u0432\u0438\u0445\u0456\u0434\u043d\u0456 \u043f\u0430\u043a\u0435\u0442\u0438. \u0417\u0430\u043b\u0438\u0448\u0456\u0442\u044c \u043f\u043e\u043b\u0435 \u043f\u043e\u0440\u043e\u0436\u043d\u0456\u043c, \u0449\u043e\u0431 \u043d\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0446\u044e \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c.
 ConfigView.section.connection.group.networks=\u041c\u0435\u0440\u0435\u0436\u0456
 ConfigView.section.connection.group.networks.info=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0442\u0438\u043f\u0438 \u043c\u0435\u0440\u0435\u0436\u0435\u0432\u0438\u0445 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0456\u0432, \u044f\u043a\u0456 \u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0456 \u0434\u0430\u043d\u0438\u0445
@@ -1436,48 +1436,48 @@ TableColumn.header.peersources.info=\u0421\u043f\u043e\u0436\u0438\u0432\u0447\u
 wizard.tracker.dht=\u0414\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0456\u0437\u043e\u0432\u0430\u043d\u0438\u0439 (\u043b\u0438\u0448\u0435 \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u043a\u043b\u0456\u0454\u043d\u0442\u0430 Vuze)
 MyTorrentsView.menu.advancedmenu=\u0414\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u043e
 MyTorrentsView.menu.networks=\u041c\u0435\u0440\u0435\u0436\u0456
-MyTorrentsView.menu.peersource=\u0414\u0436\u0435\u0440\u0435\u043b\u043e
+MyTorrentsView.menu.peersource=\u0414\u0436\u0435\u0440\u0435\u043b\u0430 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432
 ConfigView.section.sharing.permitdht=\u0414\u043e\u0437\u0432\u043e\u043b\u044f\u0442\u0438 \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0456\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0442\u0440\u0435\u043a\u0456\u043d\u0433, \u043a\u043e\u043b\u0438 \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439
-ConfigView.section.sharing.protocol=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0434\u043b\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u0456\u0432 \u043d\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 (\u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0435 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0443)
+ConfigView.section.sharing.protocol=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0434\u043b\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u0456\u0432 \u043d\u0430 \u043a\u043b\u0430\u0441\u0438\u0447\u043d\u0456\u0439 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 PeersView.Messaging=\u041e\u0431\u043c\u0456\u043d \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f\u043c\u0438
-PeersView.Messaging.info=\u041f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0430 \u043f\u043e\u043b\u0456\u043f\u0448\u0435\u043d\u043e\u0433\u043e \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u043e\u0431\u043c\u0456\u043d\u0443 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f\u043c\u0438.
-ConfigView.label.queue.newseedsmovetop=\u041f\u0435\u0440\u0435\u043c\u0456\u0449\u0443\u0432\u0430\u0442\u0438 \u0442\u0456\u043b\u044c\u043a\u0438 \u0449\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0434\u043e\u0433\u043e\u0440\u0438 \u0441\u043f\u0438\u0441\u043a\u0443 \u0441\u0456\u0434\u0435\u0440\u0456\u0432
-ConfigView.label.seeding.firstPriority.ignore.info=\u041f\u0430\u043c\u2019\u044f\u0442\u0430\u0439\u0442\u0435, \u0449\u043e \u0437\u0430\u0441\u0442\u043e\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0446\u0438\u0445 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \u043c\u043e\u0436\u0435 \u0441\u043f\u0440\u0438\u0447\u0438\u043d\u0438\u0442\u0438 \u0437\u0443\u043f\u0438\u043d\u043a\u0443 \u0442\u043e\u0440\u0435\u043d\u0442\u0430,\n\u044f\u043a \u0442\u0456\u043b\u044c\u043a\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c\u0441\u044f.
-ConfigView.label.seeding.firstPriority.ignore=\u0406\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438 \u0432\u0438\u0441\u043e\u043a\u0438\u0439 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0434\u043b\u044f:
+PeersView.Messaging.info=\u041f\u043e\u043a\u0430\u0437\u0443\u0454 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043e\u0431\u043c\u0456\u043d\u0443 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f\u043c\u0438.
+ConfigView.label.queue.newseedsmovetop=\u041f\u0435\u0440\u0435\u043c\u0456\u0449\u0443\u0432\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u0449\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0434\u043e\u0433\u043e\u0440\u0438 \u0441\u043f\u0438\u0441\u043a\u0443 \u0441\u0456\u0434\u0435\u0440\u0456\u0432
+ConfigView.label.seeding.firstPriority.ignore.info=\u041f\u0430\u043c\u2019\u044f\u0442\u0430\u0439\u0442\u0435, \u0449\u043e \u0437\u0430\u0441\u0442\u043e\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0446\u0438\u0445 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c \u043c\u043e\u0436\u0435 \u0441\u043f\u0440\u0438\u0447\u0438\u043d\u0438\u0442\u0438 \u0437\u0443\u043f\u0438\u043d\u043a\u0443 \u0442\u043e\u0440\u0435\u043d\u0442\u0430,\n\u044f\u043a \u043b\u0438\u0448\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u0442\u044c\u0441\u044f.
+ConfigView.label.seeding.firstPriority.ignore=\u041d\u0435\u0445\u0442\u0443\u0432\u0430\u0442\u0438 \u0432\u0438\u0441\u043e\u043a\u0438\u043c \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0434\u043b\u044f:
 ConfigView.label.seeding.firstPriority.ignoreSPRatio=\u0422\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437\u0456 \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f\u043c \u0441\u0456\u0434\u0435\u0440\u0456\u0432 \u0434\u043e \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0432\u0438\u0449\u0435
 ConfigView.label.seeding.firstPriority.ignore0Peer=\u0422\u043e\u0440\u0435\u043d\u0442\u0456\u0432, \u044f\u043a\u0456 \u043d\u0435 \u043c\u0430\u044e\u0442\u044c \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432
 ConfigView.section.tracker.sendjavaversionandos=\u041f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u043f\u0440\u043e \u0432\u0435\u0440\u0441\u0456\u0457 Java \u0456 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0439\u043d\u043e\u0457 \u0441\u0438\u0441\u0442\u0435\u043c\u0438
 MagnetPlugin.contextmenu.exporturi=\u0421\u043a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 Magnet URI \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0456\u043d\u0443
 ConfigView.section.plugins.dht=\u0420\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u0430 \u0411\u0414
-dht.info=\u0426\u0435 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454 \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0456\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0442\u0440\u0435\u043a\u0456\u043d\u0433, \u043e\u043a\u0440\u0456\u043c \u0446\u044c\u043e\u0433\u043e - \u0439\u043e\u0433\u043e \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u0437\u043c\u0435\u043d\u0448\u0438\u0442\u044c \u0432\u0430\u0448\u0456 \u043c\u043e\u0436\u043b\u0438\u0432\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
+dht.info=\u0426\u0435 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454 \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0456\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0442\u0440\u0435\u043a\u0456\u043d\u0433  - \u0439\u043e\u0433\u043e \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u0437\u043c\u0435\u043d\u0448\u0438\u0442\u044c \u0432\u0430\u0448\u0456 \u043c\u043e\u0436\u043b\u0438\u0432\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 dht.enabled=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0440\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u0443 \u0411\u0414
 dht.portdefault=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0439 \u043f\u043e\u0440\u0442
-dht.port=UDP-\u043f\u043e\u0440\u0442 \u0434\u043b\u044f \u0411\u0414
+dht.port=\u041f\u043e\u0440\u0442 UDP \u0434\u043b\u044f \u0411\u0414
 dht.execute.command=\u0414\u0456\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u043d\u0456 \u043a\u043e\u043c\u0430\u043d\u0434\u0438
 dht.execute.info=\u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u0434\u043b\u044f \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u043d\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0438
 dht.execute=\u0412\u0438\u043a\u043e\u043d\u0430\u0442\u0438
 dht.logging=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0432\u0456\u0434\u0441\u0442\u0435\u0436\u0435\u043d\u043d\u044f \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0456
 ConfigView.section.plugins.dhttracker=\u0420\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u0438\u0439 \u0442\u0440\u0435\u043a\u0435\u0440
-dhttracker.tracknormalwhenoffline=\u0412\u0456\u0434\u0441\u043b\u0456\u0434\u043a\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u0437\u0432\u0438\u0447\u0430\u0439\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u043a\u043e\u043b\u0438 \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439.
-ConfigView.section.file.nativedelete._mac=\u0412\u0438\u043b\u0443\u0447\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438
+dhttracker.tracknormalwhenoffline=\u041f\u0440\u043e\u0441\u0442\u0435\u0436\u0443\u0432\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u0437\u0432\u0438\u0447\u0430\u0439\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438, \u043a\u043e\u043b\u0438 \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439.
+ConfigView.section.file.nativedelete._mac=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043a\u043e\u0448\u0438\u043a
 ConfigView.section.file.nativedelete._windows=\u0412\u0438\u043b\u0443\u0447\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0438\u0439 \u043a\u043e\u0448\u0438\u043a
-ConfigView.section.logging.generatediagnostics=\u0413\u0435\u043d\u0435\u0440\u0443\u0432\u0430\u0442\u0438
-ConfigView.section.logging.netinfo=\u0413\u0435\u043d\u0435\u0440\u0443\u0432\u0430\u0442\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u043f\u0440\u043e \u043c\u0435\u0440\u0435\u0436\u0443
-ConfigView.section.logging.statsinfo=\u0413\u0435\u043d\u0435\u0440\u0443\u0432\u0430\u0442\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443
-ConfigView.section.logging.generatediagnostics.info=\u0413\u0435\u043d\u0435\u0440\u0443\u0432\u0430\u0442\u0438 \u0434\u0456\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u043d\u0443 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u0456 \u0441\u043a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0457\u0457 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0456\u043d\u0443, \u0437\u0430\u043f\u0438\u0441\u0430\u0432\u0448\u0438 \u0432 \u043b\u043e\u0433
-ConfigView.section.sharing.privatetorrent=\u041e\u0441\u043e\u0431\u0438\u0441\u0442\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442 - \u043f\u0440\u0438\u0439\u043c\u0430\u0454 \u0441\u043f\u0456\u0432\u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0442\u0456\u043b\u044c\u043a\u0438 \u0432\u0456\u0434 \u0442\u0440\u0435\u043a\u0435\u0440\u0443
-MainWindow.menu.tools.nattest=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 &NAT \u0456 \u0431\u0440\u0430\u043d\u0434\u043c\u0430\u0443\u0435\u0440\u0430
+ConfigView.section.logging.generatediagnostics=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438
+ConfigView.section.logging.netinfo=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u043f\u0440\u043e \u043c\u0435\u0440\u0435\u0436\u0443
+ConfigView.section.logging.statsinfo=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443
+ConfigView.section.logging.generatediagnostics.info=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0434\u0456\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u043d\u0443 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u0456 \u0441\u043a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0457\u0457 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0456\u043d\u0443, \u0437\u0430\u043f\u0438\u0441\u0430\u0432\u0448\u0438 \u0432 \u0444\u0430\u0439\u043b .log
+ConfigView.section.sharing.privatetorrent=\u041e\u0441\u043e\u0431\u0438\u0441\u0442\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442 - \u043f\u0440\u0438\u0439\u043c\u0430\u0454 \u0441\u043f\u0456\u0432\u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u043b\u0438\u0448\u0435 \u0432\u0456\u0434 \u0442\u0440\u0435\u043a\u0435\u0440\u0443
+MainWindow.menu.tools.nattest=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 NAT \u0456 &\u0431\u0440\u0430\u043d\u0434\u043c\u0430\u0443\u0435\u0440\u0430
 Button.apply=\u0417\u0430\u0441\u0442\u043e\u0441\u0443\u0432\u0430\u0442\u0438
 Button.close=\u0417\u0430\u043a\u0440\u0438\u0442\u0438
 window.welcome.title=\u041b\u0430\u0441\u043a\u0430\u0432\u043e \u043f\u0440\u043e\u0441\u0438\u043c\u043e \u0432 Vuze %1
 #file can be a URL or a path in the jar
 MainWindow.menu.help.releasenotes=\u0414\u043e\u043a\u043b\u0430\u0434\u043d\u043e \u043f\u0440\u043e \u0440\u0435\u043b\u0456\u0437
-dht.reseed.label=\u0417\u0432\u0438\u0447\u0430\u0439\u043d\u0435 \u043e\u0447\u0438\u0449\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u043e\u0457 \u0411\u0414 \u043d\u0435 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0435. \u041e\u0434\u043d\u0430\u043a, \u044f\u043a\u0449\u043e \u0437'\u0454\u0434\u043d\u0430\u043d\u044c \u043d\u0435\u0431\u0430\u0433\u0430\u0442\u043e, \u0446\u044f \u0444\u0443\u043d\u043a\u0446\u0456\u044f \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u0430 \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0457 \u0456\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0456\u0457.\n\u0417\u0430\u043b\u0438\u0448\u0442\u0435 \u043f\u043e\u043b\u0435 \u043f\u043e\u0440\u043e\u0436\u043d\u0456\u043c, \u0449\u043e\u0431 \u0432\u0438\u043a\u043e\u043d\u0430\u0442\u0438 \u043f\u043e\u0447\u0430\u0442\u043a\u043e\u0432\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0432\u0456\u0434 \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u043d\u043d\u0438\u0445 \u0441\u043f\u0456\u0432\u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0430\u0431\u043e \u0432\u043a\u0430\u0436\u0456\u0442\u044c IP \u0456 \u043f\u043e\u0440\u0442, \u0449\u043e\u0431 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438\u0441\u044f \u043f\u0440\u044f\u043c\u043e \u0432\u0456\u0434 \u0432\u0456\u0434\u043e\u043c\u043e\u0433\u043e \u0441\u043f\u0456\u0432\u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430.
-dht.reseed.group=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438
+dht.reseed.label=\u0417\u0430\u0437\u0432\u0438\u0447\u0430\u0439 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430 \u0440\u043e\u0437\u0434\u0430\u0447\u0430 \u0440\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u043e\u0457 \u0411\u0414 \u043d\u0435 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0430. \u041e\u0434\u043d\u0430\u043a, \u044f\u043a\u0449\u043e \u0437'\u0454\u0434\u043d\u0430\u043d\u044c \u043d\u0435\u0431\u0430\u0433\u0430\u0442\u043e, \u0446\u044f \u0444\u0443\u043d\u043a\u0446\u0456\u044f \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u0430 \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0457 \u0456\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0456\u0457.\n\u0417\u0430\u043b\u0438\u0448\u0442\u0435 \u043f\u043e\u043b\u0435 \u043f\u043e\u0440\u043e\u0436\u043d\u0456\u043c, \u0449\u043e\u0431 \u0432\u0438\u043a\u043e\u043d\u0430\u0442\u0438 \u043f\u043e\u0447\u0430\u0442\u043a\u043e\u0432\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0432\u0456\u0434 \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u043d\u043d\u0438\u0445 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0430\u0431\u043e \u0432\u043a\u0430\u0436\u0456\u0442\u044c IP \u0456 \u043f\u043e\u0440\u0442, \u0449\u043e\u0431 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438\u0441\u044f \u043f\u0440\u044f\u043c\u043e \u0432\u0456\u0434 \u0432\u0456\u0434\u043e\u043c\u043e\u0433\u043e \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430.
+dht.reseed.group=\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0440\u043e\u0437\u0434\u0430\u0442\u0438
 dht.reseed.ip=IP-\u0430\u0434\u0440\u0435\u0441\u0430
 dht.reseed.port=\u041f\u043e\u0440\u0442
-dht.reseed=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438
-dht.reseed.info=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u0411\u0414
+dht.reseed=\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0440\u043e\u0437\u0434\u0430\u0442\u0438
+dht.reseed.info=\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0440\u043e\u0437\u0434\u0430\u0442\u0438 \u0411\u0414
 dht.diagnostics.group=\u0414\u0456\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430
 DHTView.title.full=\u0420\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u0430 \u0411\u0414
 DHTView.title.fullcvs=\u0420\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u0430 \u0411\u0414 CVS
@@ -1485,7 +1485,7 @@ DHTView.general.title=\u041e\u0441\u043d\u043e\u0432\u043d\u0456
 DHTView.general.uptime=\u0427\u0430\u0441 \u0440\u043e\u0431\u043e\u0442\u0438:
 DHTView.general.users=\u041a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0456\u0432:
 DHTView.general.nodes=\u0412\u0443\u0437\u043b\u0456\u0432:
-DHTView.general.leaves=\u0417\u0430\u043b\u0438\u0448\u0438\u043b\u043e\u0441\u044f:
+DHTView.general.leaves=\u041f\u043e\u043a\u0438\u0434\u0430\u044e\u0447\u0438\u0445:
 DHTView.general.contacts=\u0417'\u0454\u0434\u043d\u0430\u043d\u044c:
 DHTView.general.replacements=\u0417\u0430\u043c\u0456\u043d\u043d\u0438\u043a\u0438:
 DHTView.general.live=\u0416\u0438\u0432\u0438\u0445:
@@ -1500,13 +1500,13 @@ DHTView.transport.in=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043
 DHTView.transport.out=\u0420\u043e\u0437\u0434\u0430\u0447\u0430 :
 DHTView.operations.title=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0457
 DHTView.operations.sent=\u0412\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0445
-DHTView.operations.ok=\u0412\u0434\u0430\u043b\u0438\u0445
-DHTView.operations.failed=\u041d\u0435\u0432\u0434\u0430\u043b\u0438\u0445
+DHTView.operations.ok=\u0413\u0430\u0440\u0430\u0437\u0434
+DHTView.operations.failed=\u041f\u043e\u043c\u0438\u043b\u043a\u0430
 DHTView.operations.received=\u041e\u0442\u0440\u0438\u043c\u0430\u043d\u0438\u0445
-DHTView.operations.ping=\u041e\u043f\u0438\u0442\u0443\u0432\u0430\u043d\u043d\u044f
+DHTView.operations.ping=\u041f\u0456\u043d\u0433
 DHTView.operations.findNode=\u041f\u043e\u0448\u0443\u043a \u0432\u0443\u0437\u043b\u0430
 DHTView.operations.findValue=\u041f\u043e\u0448\u0443\u043a \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f
-DHTView.operations.store=\u0417\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
+DHTView.operations.store=\u0417\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0438\u0445
 DHTView.activity.title=\u0410\u043a\u0442\u0438\u0432\u043d\u0456\u0441\u0442\u044c
 DHTView.activity.status=\u0421\u0442\u0430\u0442\u0443\u0441
 DHTView.activity.status.true=\u0423 \u0447\u0435\u0440\u0437\u0456
@@ -1516,8 +1516,8 @@ DHTView.activity.type.1=\u0412\u043d\u0443\u0442\u0440\u0456\u0448\u043d\u0456\u
 DHTView.activity.type.2=\u0417\u043e\u0432\u043d\u0456\u0448\u043d\u0456\u0439 \u043f\u0440\u0438\u0439\u043e\u043c
 DHTView.activity.type.3=\u0412\u043d\u0443\u0442\u0440\u0456\u0448\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0430
 DHTView.activity.type.4=\u0417\u043e\u0432\u043d\u0456\u0448\u043d\u0456\u0439 \u0440\u043e\u0437\u0434\u0430\u0447\u0430
-DHTView.activity.target=\u0426\u0456\u043b\u044c
-DHTView.activity.details=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456
+DHTView.activity.target=\u041c\u0435\u0442\u0430
+DHTView.activity.details=\u0414\u043e\u043a\u043b\u0430\u0434\u043d\u043e
 DHTView.db.title=\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u0438\u0445
 DHTView.db.keys=\u041a\u043b\u044e\u0447\u0456
 DHTView.db.values=\u0417\u043d\u0430\u0447\u0435\u043d\u043d\u044f
@@ -1527,20 +1527,20 @@ DHTView.db.indirect=\u041f\u043e\u0431\u0456\u0447\u043d\u043e
 DHTView.db.divfreq=\u0427\u0430\u0441\u0442\u043e\u0442\u0430. Div.
 DHTView.db.divsize=\u0420\u043e\u0437\u043c\u0456\u0440 Div.
 MainWindow.dht.status.tooltip=\u041a\u043e\u043b\u0438 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430 \u0440\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u0430 \u0411\u0414, \u043f\u043e\u043a\u0430\u0437\u0443\u0454\u0442\u044c\u0441\u044f \u043e\u0440\u0456\u0454\u043d\u0442\u043e\u0432\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u043d\u0438\u0445 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0456\u0432
-MainWindow.dht.status.disabled=\u0412\u0438\u043c\u043a\u043d\u0435\u043d\u043e
-MainWindow.dht.status.failed=\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f
-MainWindow.dht.status.initializing=\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0454\u0442\u044c\u0441\u044f
-MainWindow.dht.status.users=\u041a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0456
-MainWindow.dht.status.unreachable=DHT \u0437\u0430 \u0431\u0440\u0430\u043d\u0434\u043c\u0430\u0443\u0435\u0440\u043e\u043c
+MainWindow.dht.status.disabled=DHT \u0412\u0438\u043c\u043a\u043d\u0443\u0442\u043e
+MainWindow.dht.status.failed=DHT \u041f\u043e\u043c\u0438\u043b\u043a\u0430
+MainWindow.dht.status.initializing=DHT \u0406\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u044f
+MainWindow.dht.status.users=\u041a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0456: %1
+MainWindow.dht.status.unreachable=DHT \u0437\u0430\u043a\u0440\u0438\u0442\u0435 \u0431\u0440\u0430\u043d\u0434\u043c\u0430\u0443\u0435\u0440\u043e\u043c
 MainWindow.dht.status.unreachabletooltip=\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0437 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f\u043c \u043f\u043e\u0440\u0442\u0456\u0432 UDP \u0440\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u043e\u0457 \u0411\u0414 (\u0431\u0440\u0430\u043d\u0434\u043c\u0430\u0443\u0435\u0440 \u0430\u0431\u043e NAT)
 MyTorrentsView.menu.setUpSpeed=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 MyTorrentsView.menu.setDownSpeed=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 ConfigView.section.tracker.client.showwarnings=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u043f\u043e\u043f\u0435\u0440\u0435\u0434\u0436\u0435\u043d\u043d\u044f, \u044f\u043a\u0456 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u044f\u044e\u0442\u044c\u0441\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438
 dht.advanced=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0434\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u0456 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f
 dht.advanced.group=\u0414\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u0456 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f
-dht.advanced.label=\u0417\u043c\u0456\u043d\u044e\u0439\u0442\u0435 \u0446\u0456 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438, \u043b\u0438\u0448\u0435 \u044f\u043a\u0449\u043e \u0440\u043e\u0437\u0443\u043c\u0456\u0454\u0442\u0435, \u0449\u043e \u0412\u0438 \u0440\u043e\u0431\u0438\u0442\u0435
+dht.advanced.label=\u0417\u043c\u0456\u043d\u044e\u0439\u0442\u0435 \u0446\u0456 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438, \u043b\u0438\u0448\u0435, \u044f\u043a\u0449\u043e \u0440\u043e\u0437\u0443\u043c\u0456\u0454\u0442\u0435, \u0449\u043e \u0412\u0438 \u0440\u043e\u0431\u0438\u0442\u0435
 dht.override.ip=\u041f\u0456\u0434\u043c\u0456\u043d\u044e\u0432\u0430\u0442\u0438 \u0437\u043e\u0432\u043d\u0456\u0448\u043d\u044e IP-\u0430\u0434\u0440\u0435\u0441\u0443
-ConfigView.section.logging.loggerenable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043b\u043e\u0433
+ConfigView.section.logging.loggerenable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 .log
 ConfigView.section.ipfilter.blockbanning=\u0417\u0430\u0431\u0430\u043d\u0438\u0442\u0438 \u0431\u043b\u043e\u043a \u0437 256 \u0430\u0434\u0440\u0435\u0441, \u044f\u043a\u0449\u043e \u0432 \u0446\u044c\u043e\u043c\u0443 \u0431\u043b\u043e\u0446\u0456 \u0437\u0430\u0431\u0430\u043d\u0435\u043d\u0456 \u0431\u0456\u043b\u044c\u0448\u0435 \u044f\u043a
 MyTrackerView.passive=\u041f\u0430\u0441\u0438\u0432\u043d\u0438\u0439
 TableColumn.header.swarm_average_speed=\u0421\u0435\u0440\u0435\u0434\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u043e\u0442\u043e\u0447\u0435\u043d\u043d\u044f
@@ -1550,47 +1550,47 @@ TableColumn.header.comment.info=\u041a\u043e\u043c\u0435\u043d\u0442\u0430\u0440
 TableColumn.header.commenticon=\u041f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0430 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440\u044e
 TableColumn.header.commenticon.info=\u0412\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u0438 \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0443, \u044f\u043a\u0449\u043e \u0432 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0454 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 
 MyTrackerView.category=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u044f
-MainWindow.menu.file.open.torrentfortracking=\u0422\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b... (\u0442\u0456\u043b\u044c\u043a\u0438 \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430)
+MainWindow.menu.file.open.torrentfortracking=\u0422\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b... (\u043b\u0438\u0448\u0435 \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430)
 VivaldiView.title.full=\u0412\u0456\u0432\u0430\u043b\u044c\u0434\u0456
 MyTrackerView.date_added=\u0414\u043e\u0434\u0430\u043d\u0438\u0439
 ConfigView.section.tracker.portbackup=\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u0456 \u043f\u043e\u0440\u0442\u0438 (\u0440\u043e\u0437\u0434\u0456\u043b\u0435\u043d\u0456 ';')
-ConfigView.label.playfilespeech=\u0412\u0438\u043c\u043e\u0432\u043b\u044f\u0442\u0438 \u0441\u0438\u043d\u0442\u0435\u0437\u0430\u0442\u043e\u0440\u043e\u043c \u0433\u043e\u043b\u043e\u0441\u0443 \u043f\u0440\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443
-ConfigView.label.playfilespeech.info=\u0421\u0438\u043d\u0442\u0435\u0437\u0430\u0442\u043e\u0440 \u0433\u043e\u043b\u043e\u0441\u0443 \u043f\u043e\u043a\u0438 \u0449\u043e \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0430\u0446\u044e\u0454 \u0442\u0456\u043b\u044c\u043a\u0438 \u0437 \u0430\u043d\u0433\u043b\u0456\u0439\u0441\u044c\u043a\u043e\u044e \u043c\u043e\u0432\u043e\u044e
-ConfigView.label.playfilefinished=\u0412\u0456\u0434\u0442\u0432\u043e\u0440\u044e\u0432\u0430\u0442\u0438 \u0437\u0432\u0443\u043a \u043f\u0440\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443
+ConfigView.label.playfilespeech=\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u044f\u0442\u0438 \u0441\u0438\u043d\u0442\u0435\u0437\u0430\u0442\u043e\u0440\u043e\u043c \u0433\u043e\u043b\u043e\u0441\u0443 \u043f\u0440\u043e \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443
+ConfigView.label.playfilespeech.info=\u0421\u0438\u043d\u0442\u0435\u0437\u0430\u0442\u043e\u0440 \u0433\u043e\u043b\u043e\u0441\u0443 \u043f\u043e\u043a\u0438 \u0449\u043e \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0430\u0446\u044e\u0454 \u043b\u0438\u0448\u0435 \u0437 \u0430\u043d\u0433\u043b\u0456\u0439\u0441\u044c\u043a\u043e\u044e \u043c\u043e\u0432\u043e\u044e
+ConfigView.label.playfilefinished=\u0412\u0456\u0434\u0442\u0432\u043e\u0440\u044e\u0432\u0430\u0442\u0438 \u0437\u0432\u0443\u043a \u043f\u0440\u043e \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443
 ConfigView.label.backupconfigfiles=\u0420\u043e\u0431\u0438\u0442\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0456 \u043a\u043e\u043f\u0456\u0457 \u0444\u0430\u0439\u043b\u0456\u0432 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u0457 \u043d\u0430 \u0432\u0438\u043f\u0430\u0434\u043e\u043a \u0432\u0456\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u043f\u0456\u0441\u043b\u044f \u0430\u0432\u0430\u0440\u0456\u0457
-ConfigView.section.tracker.client.scrapesingleonly=\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438 \u043e\u0447\u0438\u0441\u0442\u043a\u0443 \u0437\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438 (\u043c\u043e\u0436\u0435 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u0442\u0438 \u0437 \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438, \u044f\u043a\u0456 \u0432\u0438\u0434\u0430\u044e\u0442\u044c \u043f\u043e\u043c\u0438\u043b\u043a\u0443 414 'URL \u0437\u0430\u043d\u0430\u0434\u0442\u043e \u0434\u043e\u0432\u0433\u0438\u0439') 
-dht.ipfilter.log=\u0412\u0435\u0441\u0442\u0438 \u043b\u043e\u0433 \u043f\u043e\u0440\u0443\u0448\u0435\u043d\u044c IP-\u0444\u0456\u043b\u044c\u0442\u0440\u0430 
+ConfigView.section.tracker.client.scrapesingleonly=\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0441\u0445\u043e\u0432\u0438\u0449 \u0437\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438 (\u043c\u043e\u0436\u0435 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u0442\u0438 \u0437 \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438, \u044f\u043a\u0456 \u0432\u0438\u0434\u0430\u044e\u0442\u044c \u043f\u043e\u043c\u0438\u043b\u043a\u0443 414 '\u0430\u0434\u0440\u0435\u0441\u0430 \u0437\u0430\u043d\u0430\u0434\u0442\u043e \u0434\u043e\u0432\u0433\u0430') 
+dht.ipfilter.log=\u0417\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u0442\u0438 \u0432 .log \u043f\u043e\u0440\u0443\u0448\u0435\u043d\u043d\u044f IP-\u0444\u0456\u043b\u044c\u0442\u0440\u0430 
 ConfigView.label.seeding.addForSeedingDLCopyCount=\u0412\u0440\u0430\u0445\u043e\u0432\u0443\u0432\u0430\u0442\u0438 '\u0434\u043e\u0434\u0430\u043d\u0456 \u0434\u043b\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456' \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f, \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0432 \u043a\u0456\u043b\u044c\u043a\u043e\u0441\u0442\u0456 \u043a\u043e\u043f\u0456\u0439
-ActivityView.legend.limit=\u041e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0432 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456
+ActivityView.legend.limit=\u041e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456
 ActivityView.legend.achieved=\u0414\u043e\u0441\u044f\u0433\u043d\u0443\u0442\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c
 ActivityView.legend.overhead=\u0412\u0435\u0440\u0445\u043d\u0454 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f
-ActivityView.legend.peeraverage=\u0421\u0435\u0440\u0435\u0434\u043d\u044f
+ActivityView.legend.peeraverage=\u0421\u0435\u0440\u0435\u0434\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c
 ActivityView.legend.swarmaverage=\u0421\u0435\u0440\u0435\u0434\u043d\u044f \u0437\u0430 \u043e\u0442\u043e\u0447\u0435\u043d\u043d\u044f\u043c
-ActivityView.legend.trimmed=\u0427\u0438\u0441\u0442\u0430 \u043e\u0446\u0456\u043d\u043a\u0430
+ActivityView.legend.trimmed=\u0412\u043f\u043e\u0440\u044f\u0434\u043a\u043e\u0432\u0430\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c (\u043f\u0443\u043d\u043a\u0442\u0438\u0440)
 MyTorrentsView.menu.movemenu=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0444\u0430\u0439\u043b\u0438
-MyTorrentsView.menu.movedata=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 \u0437 \u0434\u0430\u043d\u0438\u043c\u0438...
+MyTorrentsView.menu.movedata=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0444\u0430\u0439\u043b\u0438...
 MyTorrentsView.menu.movetorrent=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b...
-MyTorrentsView.menu.movedata.dialog=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u043d\u043e\u0432\u0435 \u043c\u0456\u0441\u0446\u0435
+MyTorrentsView.menu.movedata.dialog=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u043d\u043e\u0432\u0435 \u0440\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f
 DHTView.operations.data=\u0414\u0430\u043d\u0456
 DHTView.general.reachable=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439:
-DHTView.general.rendezvous=\u0422\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0456\u044f Rendezvous:
+DHTView.general.rendezvous=\u0412\u0437\u0430\u0454\u043c\u043e\u0434\u0456\u0439:
 ConfigView.label.queue.maxactivetorrentswhenseeding=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0432 \u0432\u0438\u043f\u0430\u0434\u043a\u0443 \u043b\u0438\u0448\u0435 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 [0:\u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0438\u0439]
 Views.plugins.IRC.title=IRC 
 Formats.units.persec=/\u0441
 Formats.units.TiB=\u0422\u0456\u0431
-Formats.units.Tibit=\u0422\u0456\u0431\u0456\u0442
+Formats.units.Tibit=\u0422\u0456\u0411\u0456\u0442
 Formats.units.TB=\u0422\u0411\u0430\u0439\u0442
 Formats.units.Tbit=\u0422\u0431\u0456\u0442
 Formats.units.GiB=\u0413\u0456\u0431
-Formats.units.Gibit=\u0413\u0456\u0431\u0456\u0442
+Formats.units.Gibit=\u0413\u0456\u0411\u0456\u0442
 Formats.units.GB=\u0413\u0411\u0430\u0439\u0442
 Formats.units.Gbit=\u0413\u0431\u0456\u0442
 Formats.units.MiB=\u041c\u0456\u0431
-Formats.units.Mibit=\u041c\u0456\u0431\u0456\u0442
+Formats.units.Mibit=\u041c\u0456\u0411\u0456\u0442
 Formats.units.MB=\u041c\u0411\u0430\u0439\u0442
 Formats.units.Mbit=\u041c\u0431\u0456\u0442
 Formats.units.KiB=\u041a\u0456\u0431
-Formats.units.Kibit=K\u0456\u0431\u0456\u0442
+Formats.units.Kibit=K\u0456\u0411\u0456\u0442
 Formats.units.kB=\u041a\u0431
 Formats.units.KB=\u041a\u0411\u0430\u0439\u0442
 Formats.units.kbit=\u041a\u0431\u0456\u0442
@@ -1601,13 +1601,13 @@ ConfigView.section.ipfilter.persistblocking=\u0417\u0431\u0435\u0440\u0456\u0433
 FilesView.menu.rename=\u041f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0438 \u0430\u0431\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438
 FilesView.menu.rename_only=\u041f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0438
 FilesView.menu.retarget=\u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u0438
-FilesView.rename.choose.path=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u043d\u043e\u0432\u0438\u0439 \u0430\u0431\u043e \u0456\u0441\u043d\u0443\u044e\u0447\u0438\u0439 \u0444\u0430\u0439\u043b
-FilesView.rename.choose.path.dir=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u043d\u043e\u0432\u0443 \u0430\u0431\u043e \u0456\u0441\u043d\u0443\u044e\u0447\u0443 \u0442\u0435\u043a\u0443
+FilesView.rename.choose.path=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u043d\u043e\u0432\u0438\u0439 \u0430\u0431\u043e \u043d\u0430\u044f\u0432\u043d\u0438\u0439 \u0444\u0430\u0439\u043b
+FilesView.rename.choose.path.dir=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u043d\u043e\u0432\u0443 \u0430\u0431\u043e \u043d\u0430\u044f\u0432\u043d\u0443 \u0442\u0435\u043a\u0443
 FilesView.rename.confirm.delete.title=\u041f\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0438 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f
 FilesView.rename.confirm.delete.text=\u0412\u0438 \u043f\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0436\u0443\u0454\u0442\u0435 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u043e\u0440\u0438\u0433\u0456\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0443 '%1'?
 FilesView.rename.filename.title=\u041f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0438 \u0444\u0430\u0439\u043b
 FilesView.rename.filename.text=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043d\u043e\u0432\u0435 \u0456\u043c'\u044f \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u0443
-ConfigView.higher.mode.available=\u041f\u043e\u0434\u0430\u043b\u044c\u0448\u0438\u0439 \u0432\u0438\u0431\u0456\u0440 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439 \u043b\u0438\u0448\u0435 \u0432 \u0456\u043d\u0448\u0438\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430
+ConfigView.higher.mode.available=\u041f\u043e\u0434\u0430\u043b\u044c\u0448\u0456 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u043b\u0438\u0448\u0435 \u0432 \u0456\u043d\u0448\u0438\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430
 ConfigView.section.mode=\u0420\u0435\u0436\u0438\u043c
 ConfigView.section.mode.title=\u0421\u0442\u0443\u043f\u0456\u043d\u044c \u043f\u0456\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430
 ConfigView.section.mode.beginner=\u041d\u043e\u0432\u0430\u0447\u043e\u043a
@@ -1625,17 +1625,17 @@ Files.column.fileext=\u0422\u0438\u043f
 FileItem.storage.linear=\u041b\u0456\u043d\u0456\u0439\u043d\u0438\u0439
 FileItem.storage.compact=\u041a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u0438\u0439
 MessageBoxWindow.rememberdecision=\u0417\u0430\u043f\u0430\u043c'\u044f\u0442\u0430\u0442\u0438 \u043c\u0456\u0439 \u0432\u0438\u0431\u0456\u0440
-ConfigView.section.interface.cleardecisions=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u0437\u0430\u043f\u0430\u043c'\u044f\u0442\u043e\u0432\u0430\u043d\u0456 \u0432\u0438\u0431\u043e\u0440\u0438
+ConfigView.section.interface.cleardecisions=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0456 \u0432\u0438\u0431\u043e\u0440\u0438 \u0434\u0456\u0430\u043b\u043e\u0433\u0456\u0432
 ConfigView.section.interface.cleardecisionsbutton=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438
-ConfigView.section.interface.cleartrackers=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u0442\u0440\u0435\u043a\u0435\u0440\u0438
+ConfigView.section.interface.cleartrackers=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0456 \u0442\u0440\u0435\u043a\u0435\u0440\u0438
 ConfigView.section.interface.cleartrackersbutton=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438
-ConfigView.section.interface.clearsavepaths=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u0448\u043b\u044f\u0445\u0438
+ConfigView.section.interface.clearsavepaths=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0456 \u0448\u043b\u044f\u0445\u0438
 ConfigView.section.interface.clearsavepathsbutton=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438
-configureWizard.welcome.usermodes=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0441\u0442\u0443\u043f\u0435\u043d\u044f \u0434\u043e\u0441\u0432\u0456\u0434\u0447\u0435\u043d\u043e\u0441\u0442\u0456 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 \u0437\u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0406\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438 > \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f. \u0412\u043e\u043d\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u044e\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0435\u0433\u0448\u0435\u043d\u043d\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043e\u044e.
-FilesView.skip.confirm.delete.text=\u041e\u0431\u0440\u0456\u0437\u0430\u0442\u0438 \u0444\u0430\u0439\u043b '%1' \u0434\u043b\u044f \u0435\u043a\u043e\u043d\u043e\u043c\u0456\u0457 \u043c\u0456\u0441\u0446\u044f?
+configureWizard.welcome.usermodes=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0441\u0442\u0443\u043f\u0435\u043d\u044f \u0434\u043e\u0441\u0432\u0456\u0434\u0447\u0435\u043d\u043e\u0441\u0442\u0456 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 \u0437\u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0421\u0435\u0440\u0432\u0456\u0441 > \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f. \u0412\u043e\u043d\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u044e\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0435\u0433\u0448\u0435\u043d\u043d\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043e\u044e.
+FilesView.skip.confirm.delete.text=\u041e\u0431\u0440\u0456\u0437\u0430\u0442\u0438 \u0444\u0430\u0439\u043b '%1' \u0434\u043b\u044f \u0435\u043a\u043e\u043d\u043e\u043c\u0456\u0457 \u0440\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f?
 FilesView.rename.failed.title=\u041f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0438 \u0430\u0431\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u043d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f
-FilesView.rename.failed.text=\u041e\u043f\u0435\u0440\u0430\u0446\u0456\u044f \u043f\u0435\u0440\u0435\u0440\u0432\u0430\u043d\u0430, \u043c\u043e\u0436\u043b\u0438\u0432\u043e \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u043d\u0443 \u043c\u0435\u0442\u0443
-diagnostics.log_found=Vuze \u043d\u0435 \u0431\u0443\u0432 \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u0438\u0439 \u043a\u043e\u0440\u0435\u043a\u0442\u043d\u043e. \u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, <A HREF="%1">\u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u0437\u0430\u043f\u0438\u0441 \u0432 \u043b\u043e\u0437\u0456</A> , \u044f\u043a\u0449\u043e \u0446\u0435 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438, \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u0442\u0435 \u043b\u043e\u0433\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0456 \u0440\u043e\u0437\u0440\u043e\u0431\u043d\u0438\u043a\u0456\u0432. \u0422\u0430\u043a\u043e\u0436 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0439\u0442\u0435 Wiki-\u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443 <A HREF="http://www.azureuswiki.com/index.php/Vuze_disappears">\u0417\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0440\u043e\u0431\u043e\u0442\u0438 Vuze</A> \u0434\u043b\u044f \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u0456\u0448\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457.
+FilesView.rename.failed.text=\u041e\u043f\u0435\u0440\u0430\u0446\u0456\u044f \u043f\u0435\u0440\u0435\u0440\u0432\u0430\u043d\u0430, \u043c\u043e\u0436\u043b\u0438\u0432\u043e \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432\u0438\u0431\u0440\u0430\u043d\u0443 \u043c\u0435\u0442\u0443
+diagnostics.log_found=Vuze \u043d\u0435 \u0431\u0443\u0432 \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0438\u0439 \u043a\u043e\u0440\u0435\u043a\u0442\u043d\u043e. \u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, <A HREF="%1">\u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u0437\u0430\u043f\u0438\u0441 \u0432 \u043b\u043e\u0437\u0456</A> , \u044f\u043a\u0449\u043e \u0446\u0435 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438, \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u0442\u0435 \u0444\u0430\u0439\u043b .log \u043a\u043e\u043c\u0430\u043d\u0434\u0456 \u0440\u043e\u0437\u0440\u043e\u0431\u043d\u0438\u043a\u0456\u0432. \u0422\u0430\u043a\u043e\u0436 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0439\u0442\u0435 Wiki-\u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443 <A HREF="http://www.azureuswiki.com/index.php/Vuze_disappears">\u0417\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0440\u043e\u0431\u043e\u0442\u0438 Vuze</A> \u0434\u043b\u044f \u0434\u043e\u043a\u043b\u0430\u0434\u043d\u0456\u0448\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457.
 ManagerItem.paused=\u041f\u0440\u0438\u043f\u0438\u043d\u0435\u043d\u043e
 Utils.link.visit=\u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0432\u0456\u0434\u0432\u0456\u0434\u0430\u0439\u0442\u0435
 ConfigView.section.connection.serverport.wiki=\u0413\u0430\u0440\u043d\u0438\u0439 \u0432\u0438\u0431\u0456\u0440 \u043f\u043e\u0440\u0442\u0456\u0432
@@ -1647,33 +1647,33 @@ Views.plugins.Distributed.Tracker.title=\u0420\u043e\u0437\u043f\u043e\u0434\u04
 Views.plugins.Plugin.Update.title=\u041f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f
 Views.plugins.UPnP.title.tooltip=\u0423\u043d\u0456\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u0438\u0439 Plug and Play
 openUrl.url.info=\u041f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0430 http, https, magnet \u0456 \u043d\u0435\u043e\u043f\u0440\u0430\u0446\u044c\u043e\u0432\u0430\u043d\u0438\u0445 \u0448\u0456\u0441\u0442\u043d\u0430\u0434\u0446\u044f\u0442\u0438\u0437\u043d\u0430\u0447\u043d\u0438\u0445 \u0456\u043d\u0444\u043e\u0445\u0435\u0448\u043e\u0432\u0438\u0445 \u0440\u044f\u0434\u043a\u0456\u0432
-TableColumn.header.swarm_average_completion=\u0421\u0435\u0440\u0435\u0434\u043d\u0456\u0439 \u0432\u0456\u0434\u0441\u043e\u0442\u043e\u043a \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f
-TableColumn.header.swarm_average_completion.info=\u0421\u0435\u0440\u0435\u0434\u043d\u0456\u0439 \u0432\u0456\u0434\u0441\u043e\u0442\u043e\u043a \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f \u0441\u0435\u0440\u0435\u0434 \u043e\u0442\u043e\u0447\u0435\u043d\u043d\u044f
-GeneralView.label.swarm_average_completion=\u0421\u0435\u0440\u0435\u0434\u043d\u0454 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f:
-GeneralView.label.swarm_average_completion.tooltip=\u0421\u0435\u0440\u0435\u0434\u043d\u0454 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f \u0441\u0435\u0440\u0435\u0434 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u043e\u0442\u043e\u0447\u0435\u043d\u043d\u044f
+TableColumn.header.swarm_average_completion=\u0421\u0435\u0440\u0435\u0434\u043d\u0456\u0439 \u0432\u0456\u0434\u0441\u043e\u0442\u043e\u043a \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f
+TableColumn.header.swarm_average_completion.info=\u0421\u0435\u0440\u0435\u0434\u043d\u0456\u0439 \u0432\u0456\u0434\u0441\u043e\u0442\u043e\u043a \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0441\u0435\u0440\u0435\u0434 \u043e\u0442\u043e\u0447\u0435\u043d\u043d\u044f
+GeneralView.label.swarm_average_completion=\u0421\u0435\u0440\u0435\u0434\u043d\u0456\u0439 % \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f:
+GeneralView.label.swarm_average_completion.tooltip=\u0421\u0435\u0440\u0435\u0434\u043d\u0456\u0439 % \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0441\u0435\u0440\u0435\u0434 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u043e\u0442\u043e\u0447\u0435\u043d\u043d\u044f
 MainWindow.nat.status.tooltip.unknown=\u0406\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u043f\u0440\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456\u0441\u0442\u044c \u0431\u0440\u0430\u0443\u043d\u0434\u043c\u0430\u0443\u0435\u0440\u0443 \u0430\u0431\u043e NAT \u043d\u0435\u0432\u0456\u0434\u043e\u043c\u0430 (TCP)
 MainWindow.nat.status.tooltip.ok=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0456\u0441\u0442\u044c \u0432 \u043d\u043e\u0440\u043c\u0456 (TCP)
 MainWindow.nat.status.tooltip.probok=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0456\u0441\u0442\u044c \u0432 \u043d\u043e\u0440\u043c\u0456, \u043e\u0434\u043d\u0430\u043a \u043f\u043e\u043a\u0438 \u0432\u0445\u0456\u0434\u043d\u0438\u0445 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c TCP \u043d\u0435 \u0431\u0443\u043b\u043e
 MainWindow.nat.status.bad=\u0417\u0430\u0445\u0438\u0449\u0435\u043d\u0456 \u0431\u0440\u0430\u043d\u0434\u043c\u0430\u0443\u0435\u0440\u043e\u043c
 MainWindow.nat.status.tooltip.bad=\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0437 \u0431\u0440\u0430\u043d\u0434\u043c\u0430\u0443\u0435\u0440\u043e\u043c \u0430\u0431\u043e NAT. \u0417\u0430\u0433\u043b\u044f\u043d\u044c\u0442\u0435 \u0432 Wiki \u0434\u043b\u044f \u0434\u043e\u0432\u0456\u0434\u043a\u0438
 plugin.installer.recommended.plugin=\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u043d\u0435 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f - \u0431\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u043e\u0446\u0456\u043d\u0456\u0442\u044c \u0456 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0456\u0442\u044c, \u044f\u043a\u0449\u043e \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e
-LoggerView.pause=\u041f\u0440\u0438\u0437\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u043b\u043e\u0433
+LoggerView.pause=\u041f\u0440\u0438\u0437\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0432 \u0444\u0430\u0439\u043b .log
 LoggerView.clear=&\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438
 LoggerView.filter=\u0424\u0456\u043b\u044c\u0442\u0440
 LoggerView.filter.uncheckAll=\u0417\u043d\u044f\u0442\u0438 \u043f\u043e\u0437\u043d\u0430\u0447\u043a\u0443 \u0443 \u0432\u0441\u0456\u0445 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0439
 LoggerView.filter.checkAll=\u041f\u043e\u0437\u043d\u0430\u0447\u0438\u0442\u0438 \u0432\u0441\u0456 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457
-LoggerView.loggingDisabled=\u041b\u043e\u0433 \u043d\u0435 \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u0439.
+LoggerView.loggingDisabled=\u0417\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0432 .log \u043d\u0435 \u0432\u0438\u043a\u043e\u043d\u0443\u0454\u0442\u044c\u0441\u044f.
 LoggerView.includeOnly=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u043b\u0456\u043d\u0456\u0457, \u044f\u043a\u0456 \u0441\u043f\u0456\u0432\u043f\u0430\u0434\u0430\u044e\u0442\u044c \u0437 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u0438\u043c \u0432\u0438\u0440\u0430\u0437\u043e\u043c
 LoggerView.excludeAll=\u041d\u0435 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u043b\u0456\u043d\u0456\u0457, \u044f\u043a\u0456 \u0441\u043f\u0456\u0432\u043f\u0430\u0434\u0430\u044e\u0442\u044c \u0437 \u0446\u0438\u043c \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u0438\u043c \u0432\u0438\u0440\u0430\u0437\u043e\u043c:
 ConfigView.section.logging.log0type=\u0406\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f
-ConfigView.section.logging.log1type=\u0423\u0432\u0430\u0433\u0430
-ConfigView.section.logging.log2type=\u041f\u043e\u043c\u0438\u043b\u043a\u0430
-ConfigView.section.logging.filter=\u0424\u0456\u043b\u044c\u0442\u0440\u0443\u0432\u0430\u0442\u0438 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0437\u0430\u043f\u0438\u0441\u0443 \u043b\u043e\u0433\u0443 \u0443 \u0444\u0430\u0439\u043b
-ConfigView.section.logging.level=\u0421\u0442\u0443\u043f\u0456\u043d\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c \u043b\u043e\u0433\u0443
-ConfigView.section.logging.showLogsFor=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u043b\u043e\u0433\u0438 %1  \u0437\u0430 \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u0438\u043c\u0438 \u043a\u0440\u0438\u0442\u0435\u0440\u0456\u044f\u043c\u0438:
+ConfigView.section.logging.log1type=\u041f\u043e\u043f\u0435\u0440\u0435\u0434\u0436\u0435\u043d\u044c
+ConfigView.section.logging.log2type=\u041f\u043e\u043c\u0438\u043b\u043e\u043a
+ConfigView.section.logging.filter=\u0424\u0456\u043b\u044c\u0442\u0440\u0443\u0432\u0430\u0442\u0438 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0432 \u0444\u0430\u0439\u043b .log
+ConfigView.section.logging.level=\u0421\u0442\u0443\u043f\u0456\u043d\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c \u0444\u0430\u0439\u043b\u0443 .log
+ConfigView.section.logging.showLogsFor=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 .log %1 \u0437\u0430 \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u0438\u043c\u0438 \u043a\u0440\u0438\u0442\u0435\u0440\u0456\u044f\u043c\u0438:
 ConfigView.pluginlist.column.loadAtStartup=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443
 ConfigView.pluginlist.column.type=\u0422\u0438\u043f
-ConfigView.pluginlist.column.type.perUser=\u0414\u043b\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430
+ConfigView.pluginlist.column.type.perUser=\u041a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430
 ConfigView.pluginlist.column.type.shared=\u0420\u043e\u0437\u0434\u0430\u043d\u0438\u0439
 ConfigView.pluginlist.column.type.builtIn=\u0412\u0431\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0439
 ConfigView.pluginlist.column.name=\u0406\u043c'\u044f
@@ -1681,17 +1681,17 @@ ConfigView.pluginlist.column.version=\u0412\u0435\u0440\u0441\u0456\u044f
 ConfigView.pluginlist.column.directory=\u0422\u0435\u043a\u0430
 ConfigView.pluginlist.column.isOperational=\u041f\u0440\u0430\u0446\u044e\u0454?
 PeersView.BlockView.Avail.Have=\u0404 \u0432 \u043e\u0431\u043e\u0445
-PeersView.BlockView.Avail.NoHave=\u0412 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 \u0454; \u0432 \u0412\u0430\u0441 \u043d\u0435\u043c\u0430\u0454
-PeersView.BlockView.NoAvail.Have=\u0412 \u0412\u0430\u0441 \u0454; \u0432 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 \u043d\u0435\u043c\u0430\u0454
-PeersView.BlockView.NoAvail.NoHave=\u0412 \u043e\u0431\u043e\u0445 \u043d\u0435\u043c\u0430\u0454
+PeersView.BlockView.Avail.NoHave=\u0412 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 \u0454; \u0432 \u0412\u0430\u0441 \u043d\u0435\u043c\u0430
+PeersView.BlockView.NoAvail.Have=\u0412 \u0412\u0430\u0441 \u0454; \u0432 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 \u043d\u0435\u043c\u0430
+PeersView.BlockView.NoAvail.NoHave=\u0412 \u043e\u0431\u043e\u0445 \u043d\u0435\u043c\u0430
 PeersView.BlockView.Transfer=\u041f\u0435\u0440\u0435\u0434\u0430\u0454\u0442\u044c\u0441\u044f \u0437\u0430\u0440\u0430\u0437
 PeersView.BlockView.NextRequest=\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u0438\u0439 \u0437\u0430\u043f\u0438\u0442
 PeersView.BlockView.title=\u041a\u0430\u0440\u0442\u0430 \u0447\u0430\u0441\u0442\u0438\u043d
 PeersView.BlockView.AvailCount=\u0406\u043d\u0434\u0435\u043a\u0441 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0456
-MyTorrentsView.dialog.NumberError.title=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0435 \u0430\u0431\u043e \u043d\u0435\u0432\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u0435 \u0447\u0438\u0441\u043b\u043e
-MyTorrentsView.dialog.NumberError.text=\u0412\u043a\u0430\u0437\u0430\u043d\u0435 \u0447\u0438\u0441\u043b\u043e \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0435 \u0430\u0431\u043e \u043d\u0435\u0432\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u0435.
+MyTorrentsView.dialog.NumberError.title=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0435 \u0430\u0431\u043e \u043d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u0435 \u0447\u0438\u0441\u043b\u043e
+MyTorrentsView.dialog.NumberError.text=\u0412\u043a\u0430\u0437\u0430\u043d\u0435 \u0447\u0438\u0441\u043b\u043e \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0435 \u0430\u0431\u043e \u043d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u0435.
 MyTorrentsView.menu.manual=&\u0412\u0440\u0443\u0447\u043d\u0443..
-MyTorrentsView.menu.manual.per_torrent=\u0412\u0440\u0443\u0447\u043d\u0443 (\u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442)
+MyTorrentsView.menu.manual.per_torrent=\u0412\u0440\u0443\u0447\u043d\u0443 (\u0434\u043b\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443)
 MyTorrentsView.menu.manual.shared_torrents=\u0412\u0440\u0443\u0447\u043d\u0443 (\u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u0440\u0435\u043d\u0442\u0438)
 MyTorrentsView.dialog.setSpeed.title=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c %1
 # %1 = "in kbps" or ""; %2 = "upload" or "download"
@@ -1699,7 +1699,7 @@ MyTorrentsView.dialog.setNumber.text=\u0412\u043a\u0430\u0436\u0456\u0442\u044c
 MyTorrentsView.dialog.setNumber.upload=\u0440\u043e\u0437\u0434\u0430\u0447\u0430
 MyTorrentsView.dialog.setNumber.download=\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 MyTorrentsView.dialog.setNumber.inKbps=\u0432 %1
-OpenTorrentWindow.torrentLocation=\u0424\u0430\u0439\u043b\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432:\n(\u043a\u043e\u0436\u0435\u043d \u0442\u043e\u0440\u0435\u043d\u0442 \u0432 \u0441\u0432\u043e\u0454\u043c\u0443 \u0440\u044f\u0434\u043a\u0443)
+OpenTorrentWindow.torrentLocation=\u0424\u0430\u0439\u043b\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432:
 OpenTorrentWindow.addFiles.URL=\u0414\u043e\u0434\u0430\u0442\u0438 &\u0430\u0434\u0440\u0435\u0441\u0443
 OpenTorrentWindow.addFiles.Folder=\u0414\u043e\u0434\u0430\u0442\u0438 &\u0442\u0435\u043a\u0443
 OpenTorrentWindow.addFiles.Clipboard=\u0414\u043e\u0434\u0430\u0442\u0438 \u0437 \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u0431\u043c\u0456\u043d\u0443
@@ -1718,8 +1718,8 @@ OpenTorrentWindow.mb.alreadyExists.text=<A HREF="%1">%3</A> \u0432\u0436\u0435 \
 OpenTorrentWindow.mb.alreadyExists.default.name=\u041c\u0435\u0434\u0456\u0430
 OpenTorrentWindow.mb.alreadyExists.title=\u0422\u0430\u043a\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442 \u0432\u0436\u0435 \u0456\u0441\u043d\u0443\u0454
 OpenTorrentWindow.mb.openError.title=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443
-OpenTorrentWindow.mb.openError.text='%1' \u043d\u0435 \u0432\u0434\u0430\u0454\u0442\u044c\u0441\u044f \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438:
-OpenTorrentWindow.torrent.remove=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u0437\u0456 \u0441\u043f\u0438\u0441\u043a\u0443
+OpenTorrentWindow.mb.openError.text='%1' \u043d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438:\n%2
+OpenTorrentWindow.torrent.remove=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u0437 \u0441\u043f\u0438\u0441\u043a\u0443
 OpenTorrentWindow.torrent.options=\u0414\u043e \u0432\u043a\u0430\u0437\u0430\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0431\u0443\u0434\u0443\u0442\u044c \u0437\u0430\u0441\u0442\u043e\u0441\u043e\u0432\u0430\u043d\u0456 \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u0456 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f:
 OpenTorrentWindow.xOfTotal=(%1 \u0437 %2)
 iconBar.open.tooltip=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b
@@ -1728,18 +1728,18 @@ Tracker.tooltip.MultiSupport=\u0426\u0435\u0439 \u0442\u0440\u0435\u043a\u0435\u
 Tracker.tooltip.NoMultiSupport=\u0426\u0435\u0439 \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0435 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454 \u043c\u043d\u043e\u0436\u0438\u043d\u043d\u0456 \u0445\u0435\u0448-\u0447\u0430\u0441\u0442\u0438\u043d\u0438 \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u0437\u0430\u043f\u0438\u0442\u0443.
 ConfigView.label.lazybitfield=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 '\u043b\u0435\u0434\u0430\u0447\u0443' \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 (\u0434\u043e\u043f\u043e\u043c\u0430\u0433\u0430\u0454 \u043f\u043e\u0448\u0438\u0440\u0435\u043d\u043d\u044e \u0432 \u043c\u0435\u0440\u0435\u0436\u0430\u0445, \u044f\u043a\u0456 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0442\u044c \u0431\u043b\u043e\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u0440\u043e\u0437\u043c\u0456\u0449\u0435\u043d\u043e\u0433\u043e \u0431\u0456\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f)
 LoggerView.realtime=\u041f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0447\u0430\u0441\u0456
-ConfigView.section.file.perf.cache.flushpieces=\u0417\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0447\u0430\u0441\u0442\u0438\u043d\u0438 \u043d\u0435\u0433\u0430\u0439\u043d\u043e. \u0426\u0435 \u0441\u043f\u0440\u0438\u0447\u0438\u043d\u0438\u0442\u044c \u043f\u043e\u0441\u0442\u0456\u0439\u043d\u0438\u0439, \u043f\u0440\u043e\u0442\u0435 \u0431\u0435\u0437\u043f\u0435\u0440\u0435\u0440\u0432\u043d\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441 \u0437\u0430\u043f\u0438\u0441\u0443
+ConfigView.section.file.perf.cache.flushpieces=\u0417\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0447\u0430\u0441\u0442\u0438\u043d\u0438 \u043d\u0435\u0433\u0430\u0439\u043d\u043e. \u0426\u0435 \u0441\u043f\u0440\u0438\u0447\u0438\u043d\u0438\u0442\u044c \u043f\u043e\u0441\u0442\u0456\u0439\u043d\u0438\u0439, \u0431\u0435\u0437\u043f\u0435\u0440\u0435\u0440\u0432\u043d\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441 \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f.
 ConfigView.section.file.writemblimit=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0442\u0456\u0432 \u043d\u0430 \u0437\u0430\u043f\u0438\u0441 \u0432 \u0447\u0435\u0440\u0437\u0456 (\u0432 %1)
-ConfigView.section.file.writemblimit.explain=\u042f\u043a\u0449\u043e \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0443 \u043d\u0430 \u0434\u0438\u0441\u043a \u043c\u0435\u043d\u0448\u0435 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f, \u0446\u0435\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043e\u0431\u043c\u0435\u0436\u0443\u0454 \u0440\u043e\u0437\u043c\u0456\u0440 \u0431\u0443\u0444\u0435\u0440\u0443, \u043f\u0435\u0440\u0448 \u043d\u0456\u0436 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u0434\u0435 \u0437\u043c\u0435\u043d\u0448\u0435\u043d\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043e\u044e
+ConfigView.section.file.writemblimit.explain=\u042f\u043a\u0449\u043e \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0430 \u0434\u0438\u0441\u043a \u043c\u0435\u043d\u0448\u0435 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f, \u0446\u0435\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043e\u0431\u043c\u0435\u0436\u0443\u0454 \u0440\u043e\u0437\u043c\u0456\u0440 \u0431\u0443\u0444\u0435\u0440\u0443, \u043f\u0435\u0440\u0448 \u043d\u0456\u0436 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u0434\u0435 \u0437\u043c\u0435\u043d\u0448\u0435\u043d\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043e\u044e
 ConfigView.section.file.readmblimit=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0442\u0456\u0432 \u043d\u0430 \u0447\u0438\u0442\u0430\u043d\u043d\u044f \u0432 \u0447\u0435\u0440\u0437\u0456 (\u0432 %1)
 ConfigView.section.file.readmblimit.explain=\u0426\u0435\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043e\u0431\u043c\u0435\u0436\u0443\u0454 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043f\u0430\u043c'\u044f\u0442\u0456, \u044f\u043a\u0430 \u0437\u0431\u0435\u0440\u0456\u0433\u0430\u0454 \u043e\u043f\u0435\u0440\u0430\u0446\u0456\u0457 \u0447\u0438\u0442\u0430\u043d\u043d\u044f.
 Button.moveUp=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 &\u043d\u0430\u0433\u043e\u0440\u0443
 Button.moveDown=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438 &\u0432\u043d\u0438\u0437
 ConfigView.notAvailableForMode=\u0426\u044f \u0441\u0435\u043a\u0446\u0456\u044f \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0440\u0456\u0432\u043d\u044f \u0434\u043e\u0441\u0432\u0456\u0434\u0447\u0435\u043d\u043e\u0441\u0442\u0456 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 %1 \u0430\u0431\u043e \u0432\u0438\u0449\u0435. \u0412 \u0440\u0435\u0436\u0438\u043c\u0456 %2 \u0446\u0456 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u044e\u0442\u044c\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e.
-health.explain.error=\u043e\u0437\u043d\u0430\u0447\u0430\u0454, \u0449\u043e \u0432\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u0437 \u0442\u043e\u0440\u0435\u043d\u0442\u043e\u043c. \u0414\u0438\u0432\u0456\u0442\u044c\u0441\u044f \u0441\u0442\u043e\u0432\u043f\u0435\u0446\u044c \u0441\u0442\u0430\u0442\u0443\u0441\u0443, \u0430\u0431\u043e \u043f\u0456\u0434\u043a\u0430\u0437\u043a\u0443 \u043d\u0430 \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0456 \u043f\u0440\u043e \u0446\u044e \u043f\u043e\u043c\u0438\u043b\u043a\u0443.
+health.explain.error=\u043e\u0437\u043d\u0430\u0447\u0430\u0454, \u0449\u043e \u0432\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u0437 \u0442\u043e\u0440\u0435\u043d\u0442\u043e\u043c, \u0434\u0438\u0432\u0456\u0442\u044c\u0441\u044f \u0441\u0442\u043e\u0432\u043f\u0435\u0446\u044c \u0441\u0442\u0430\u0442\u0443\u0441\u0443, \u0430\u0431\u043e \u043f\u0456\u0434\u043a\u0430\u0437\u043a\u0443 \u043d\u0430 \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0456 \u043f\u0440\u043e \u0446\u044e \u043f\u043e\u043c\u0438\u043b\u043a\u0443.
 GeneralView.label.trackerscrapeupdate=\u041e\u0447\u0438\u0449\u0443\u0432\u0430\u0442\u0438 \u0442\u0440\u0435\u043a\u0435\u0440
 PeersView.piece=\u0427\u0430\u0441\u0442\u0438\u043d\u0430
-PeersView.piece.info=\u041e\u0441\u0442\u0430\u043d\u043d\u044f \u0447\u0430\u0441\u0442\u0438\u043d\u0430 #, \u0437\u0430\u043f\u0438\u0442\u0430\u043d\u0430 \u0432 \u0446\u044c\u043e\u0433\u043e \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
+PeersView.piece.info=\u041e\u0441\u0442\u0430\u043d\u043d\u044f \u0447\u0430\u0441\u0442\u0438\u043d\u0430, \u0437\u0430\u043f\u0438\u0442\u0430\u043d\u0430 \u0432 \u0446\u044c\u043e\u0433\u043e \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
 PiecesView.priority=\u041f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442
 PiecesView.priority.info=\u0426\u0435 \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442 \u0446\u0456\u043b\u0456\u0441\u043d\u043e\u0441\u0442\u0456 \u0447\u0430\u0441\u0442\u0438\u043d\u0438, \u0430\u043b\u0435 \u043d\u0435 \u0437\u0432\u0435\u0440\u0442\u0430\u0439\u0442\u0435 \u0443\u0432\u0430\u0433\u0438 \u043d\u0430 \u043d\u044c\u043e\u0433\u043e
 PiecesView.speed=\u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c
@@ -1756,37 +1756,37 @@ Plugin.localtracker.info=\u041f\u043e\u0448\u0443\u043a \u0443\u0447\u0430\u0441
 Plugin.localtracker.enable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u043e\u0448\u0443\u043a \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0457 \u043c\u0435\u0440\u0435\u0436\u0456
 azinstancehandler.alert.portclash=\u0412\u0438\u044f\u0432\u043b\u0435\u043d\u0438\u0439 \u043a\u043e\u043d\u0444\u043b\u0456\u043a\u0442 \u043f\u043e\u0440\u0442\u0456\u0432 \u0443 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0456\u0439 \u043c\u0435\u0440\u0435\u0436\u0456: %1 \u0432\u0436\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0456\u043d\u0448\u0438\u043c \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 Vuze, \u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0431\u0443\u0434\u044c-\u044f\u043a\u0438\u0439 \u0456\u043d\u0448\u0438\u0439 \u043f\u043e\u0440\u0442 \u0434\u043b\u044f \u0432\u0445\u0456\u0434\u043d\u043e\u0433\u043e TCP / UDP [\u0443 \u0434\u0456\u0430\u043f\u0430\u0437\u043e\u043d\u0456 \u0432\u0456\u0434 %2 \u0434\u043e %3]. 
 ConfigView.section.transfer.lan=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u0430 \u043c\u0435\u0440\u0435\u0436\u0430
-ConfigView.section.transfer.lan.tooltip=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0457 \u043c\u0435\u0440\u0435\u0436\u0456
+ConfigView.section.transfer.lan.tooltip=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0435\u0432\u043d\u043e\u0457 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0457 \u043c\u0435\u0440\u0435\u0436\u0456
 ConfigView.section.transfer.lan.uploadrate=- \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0456\u0439 \u043c\u0435\u0440\u0435\u0436\u0456, \u041a\u0431\u0456\u0442/\u0441 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
 ConfigView.section.transfer.lan.uploadrate.tooltip=\u0417'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0432 \u0442\u0456\u0439 \u0441\u0430\u043c\u0456\u0439 \u0432\u043d\u0443\u0442\u0440\u0456\u0448\u043d\u0456\u0439 \u043c\u0435\u0440\u0435\u0436\u0456 \u043c\u0430\u044e\u0442\u044c \u0440\u0456\u0437\u043d\u0456 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456.
-ConfigView.section.transfer.lan.downloadrate=- \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0432 \u043c\u0435\u0440\u0435\u0436\u0456, \u041a\u0431\u0456\u0442/\u0441 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
+ConfigView.section.transfer.lan.downloadrate=- \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0456\u0439 \u043c\u0435\u0440\u0435\u0436\u0456, \u041a\u0431\u0456\u0442/\u0441 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
 ConfigView.section.transfer.lan.downloadrate.tooltip=\u0417'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0432 \u0442\u0456\u0439 \u0441\u0430\u043c\u0456\u0439 \u0432\u043d\u0443\u0442\u0440\u0456\u0448\u043d\u0456\u0439 \u043c\u0435\u0440\u0435\u0436\u0456 \u043c\u0430\u044e\u0442\u044c \u0440\u0456\u0437\u043d\u0456 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.
 TorrentOptionsView.title.short=\u041e\u043f\u0446\u0456\u0457
 TorrentOptionsView.title.full=\u041e\u043f\u0446\u0456\u0457
 TorrentOptionsView.param.max.peers=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437'\u0454\u0434\u043d\u0430\u043d\u044c [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
-ConfigView.section.connection.encryption.require_encrypted_transport=\u0412 \u043c\u0435\u043d\u0435 \u0454 \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f
+ConfigView.section.connection.encryption.require_encrypted_transport=\u0412\u0438\u043c\u0430\u0433\u0430\u0442\u0438 \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u0440\u0430\u0444\u0456\u043a\u0443
 ConfigView.section.connection.encryption.require_encrypted_transport.tooltip=\u041f\u0440\u0438\u043c\u0443\u0448\u0443\u0432\u0430\u0442\u0438 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0456 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0437 \u0456\u043d\u0448\u0438\u043c\u0438 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c\u0438
 ConfigView.section.connection.encryption.min_encryption_level=\u041c\u0456\u043d\u0456\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u0456\u0432\u0435\u043d\u044c \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f
 ConfigView.section.connection.encryption.min_encryption_level.tooltip=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0439 - \u043b\u0438\u0448\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a\nRC4 - \u043f\u043e\u0432\u043d\u0438\u0439 \u043f\u043e\u0442\u0456\u043a\n\u0412\u0438\u0449\u0438\u0439 \u0440\u0456\u0432\u0435\u043d\u044c \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043c\u043e\u0433\u0443\u0442\u043d\u0456\u0448\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u043e\u0440\u0430
 Peers.column.Encryption=\u0428\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f
 Peers.column.Encryption.info=\u0420\u0456\u0432\u0435\u043d\u044c \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f, \u044f\u043a\u0438\u0439 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f
-ConfigView.section.connection.encryption.encrypt.info=\u042f\u043a\u0449\u043e \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0435 \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f, \u0412\u0438 \u043d\u0435 \u0437\u043c\u043e\u0436\u0435\u0442\u0435 \u0437'\u0454\u0434\u043d\u0443\u0432\u0430\u0442\u0438\u0441\u044f \u0437 \u043d\u0435\u0441\u0443\u043c\u0456\u0441\u043d\u0438\u043c\u0438 \u043a\u043b\u0456\u0454\u043d\u0442\u0430\u043c\u0438, \u0434\u043e\u043a\u0438 \u043d\u0435 \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u0442\u0435 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0440\u0435\u0437\u0435\u0440\u0432\u0443\u0432\u0430\u043d\u043d\u044f
+ConfigView.section.connection.encryption.encrypt.info=\u042f\u043a\u0449\u043e \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0435 \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f, \u0412\u0438 \u043d\u0435 \u0437\u043c\u043e\u0436\u0435\u0442\u0435 \u0437'\u0454\u0434\u043d\u0443\u0432\u0430\u0442\u0438\u0441\u044f \u0437 \u043d\u0435\u0441\u0443\u043c\u0456\u0441\u043d\u0438\u043c\u0438 \u043a\u043b\u0456\u0454\u043d\u0442\u0430\u043c\u0438, \u043f\u043e\u043a\u0438 \u043d\u0435 \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u0442\u0435 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0440\u0435\u0437\u0435\u0440\u0432\u0443\u0432\u0430\u043d\u043d\u044f
 ConfigView.section.connection.encryption.encrypt.info.link=\u0412\u0456\u0434\u0432\u0456\u0434\u0430\u0439\u0442\u0435 \u0441\u0430\u0439\u0442 \u0434\u043b\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c
 MainWindow.sr.status.tooltip.ok=\u041a\u043e\u0435\u0444\u0456\u0446\u0456\u0454\u043d\u0442 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 %1 \u0433\u0430\u0440\u043d\u0438\u0439
 MainWindow.sr.status.tooltip.poor=\u041a\u043e\u0435\u0444\u0456\u0446\u0456\u0454\u043d\u0442 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 %1 \u0437\u0430\u0434\u043e\u0432\u0456\u043b\u044c\u043d\u0438\u0439: < 0.5
 MainWindow.sr.status.tooltip.bad=\u041a\u043e\u0435\u0444\u0456\u0446\u0456\u0454\u043d\u0442 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 %1 \u043f\u043e\u0433\u0430\u043d\u0438\u0439: < 0.5
-ConfigView.section.style.status=\u0414\u0456\u043b\u044f\u043d\u043a\u0430 \u0441\u0442\u0430\u0442\u0443\u0441\u0443:
+ConfigView.section.style.status=\u0414\u0456\u043b\u044f\u043d\u043a\u0430 \u0441\u0442\u0430\u043d\u0443:
 ConfigView.section.style.status.show_sr=\u041a\u043e\u0435\u0444\u0456\u0446\u0456\u0454\u043d\u0442 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 ConfigView.section.style.status.show_nat=\u0421\u0442\u0430\u043d NAT
 ConfigView.section.style.status.show_ddb=\u0421\u0442\u0430\u043d \u0420\u0411\u0414
-ConfigView.section.style.status.show_ipf=\u0421\u0442\u0430\u0442\u0443\u0441 IP-\u0444\u0456\u043b\u044c\u0442\u0440\u0443
+ConfigView.section.style.status.show_ipf=\u0421\u0442\u0430\u043d \u0444\u0456\u043b\u044c\u0442\u0440\u0443 IP
 ConfigView.section.connection.encryption.encrypt.group=\u0428\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u0456 \u043f\u0440\u0438\u0445\u043e\u0432\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u0440\u0430\u0444\u0456\u043a\u0443
 ConfigView.section.connection.encryption.encrypt.fallback_info=\u0412\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0440\u0435\u0437\u0435\u0440\u0432\u0443\u0432\u0430\u043d\u043d\u044f \u0434\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u0437'\u0454\u0434\u043d\u0443\u0432\u0430\u0442\u0438\u0441\u044f \u0437 \u043d\u0435\u0441\u0443\u043c\u0456\u0441\u043d\u0438\u043c\u0438 \u043a\u043b\u0456\u0454\u043d\u0442\u0430\u043c\u0438, \u0442\u0430 \u0441\u043f\u0440\u0438\u0447\u0438\u043d\u0438\u0442\u044c \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f
 ConfigView.section.connection.encryption.encrypt.fallback_outgoing=\u0414\u043e\u0437\u0432\u043e\u043b\u044f\u0442\u0438 \u043d\u0435\u0437\u0430\u0445\u0438\u0449\u0435\u043d\u0456 \u0432\u0438\u0445\u0456\u0434\u043d\u0456 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f, \u044f\u043a\u0449\u043e \u043d\u0435 \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u0456 \u0437\u0430\u0445\u0438\u0449\u0435\u043d\u0456
 ConfigView.section.connection.encryption.encrypt.fallback_incoming=\u0414\u043e\u0437\u0432\u043e\u043b\u044f\u0442\u0438 \u043d\u0435\u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0456 \u0432\u0445\u0456\u0434\u043d\u0456 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f
 ConfigView.section.connection.encryption=\u0428\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u0440\u0430\u0444\u0456\u043a\u0443
-upnp.selectedinterfaces=\u041e\u0431\u0440\u0430\u043d\u0456 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0438 (';' =\u0440\u043e\u0437\u0434\u0456\u043b\u0435\u043d\u0456, \u0442\u043e\u0431\u0442\u043e, eth0;eth1) [\u043f\u043e\u0440\u043e\u0436\u043d\u0454: \u0432\u0441\u0456]
-ConfigView.section.style.defaultSortOrder=\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043e\u0440\u0442\u0443\u0432\u0430\u043d\u043d\u044f, \u044f\u043a\u0438\u0439 \u0437\u0430\u0437\u0432\u0438\u0447\u0430\u0439 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f
+upnp.selectedinterfaces=\u0412\u0438\u0431\u0440\u0430\u043d\u0456 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0438 (';' =\u0440\u043e\u0437\u0434\u0456\u043b\u0435\u043d\u0456, \u0442\u043e\u0431\u0442\u043e, eth0;eth1) [\u043f\u043e\u0440\u043e\u0436\u043d\u0454: \u0432\u0441\u0456]
+ConfigView.section.style.defaultSortOrder=\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043e\u0440\u0442\u0443\u0432\u0430\u043d\u043d\u044f, \u044f\u043a\u0438\u0439 \u0437\u0432\u0438\u0447\u0430\u0439\u043d\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f
 ConfigView.section.style.defaultSortOrder.desc=\u0417\u043c\u0435\u043d\u0448\u0443\u0432\u0430\u043d\u0438\u0439
 ConfigView.section.style.defaultSortOrder.asc=\u0417\u0431\u0456\u043b\u044c\u0448\u0443\u0432\u0430\u043d\u0438\u0439
 ConfigView.section.style.defaultSortOrder.flip=\u041f\u0440\u043e\u0442\u0438\u043b\u0435\u0436\u043d\u0438\u0439 \u043f\u043e\u043f\u0435\u0440\u0435\u0434\u043d\u044c\u043e\u043c\u0443
@@ -1794,10 +1794,10 @@ LoggerView.autoscroll=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u04
 Button.selectAll=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0432\u0441\u0435
 Button.markSelected=\u041f\u043e\u0437\u043d\u0430\u0447\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043d\u0435
 Button.unmarkSelected=\u0417\u043d\u044f\u0442\u0438 \u043f\u043e\u0437\u043d\u0430\u0447\u043a\u0443 \u0437 \u0432\u0438\u0431\u0440\u0430\u043d\u0438\u0445
-plugins.basicview.config=\u041a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u044f
+plugins.basicview.config=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f
 TorrentOptionsView.param.max.uploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0441\u043b\u043e\u0442\u0456\u0432 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 [\u043c\u0456\u043d\u0456\u043c\u0443\u043c: 2]
 MyTorrentsView.dialog.setPosition.title=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u043e\u0437\u0438\u0446\u0456\u044e
-MyTorrentsView.dialog.setPosition.text=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0456\u0442\u044c \u043f\u043e\u0437\u0438\u0446\u0456\u044e \u0434\u043b\u044f \u0432\u0438\u0431\u0440\u0430\u043d\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u0456\u0432, \u0432\u043a\u0430\u0437\u0430\u0432\u0448\u0438 \u0457\u0457:
+MyTorrentsView.dialog.setPosition.text=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0456\u0442\u044c \u043f\u043e\u0437\u0438\u0446\u0456\u044e \u0434\u043b\u044f \u0432\u0438\u0431\u0440\u0430\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432, \u0432\u043a\u0430\u0437\u0430\u0432\u0448\u0438 \u0457\u0457:
 MyTorrentsView.menu.reposition.manual=\u0412\u0438\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f..
 ConfigView.section.connection.advanced.info.link=\u0412\u0456\u0434\u0432\u0456\u0434\u0430\u0439\u0442\u0435 \u0441\u0430\u0439\u0442 \u0434\u043b\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c
 ConfigView.section.connection.advanced.socket.group=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0441\u043e\u043a\u0435\u0442\u0443
@@ -1806,8 +1806,8 @@ ConfigView.section.connection.advanced.bind_port.tooltip=\u0412\u0438\u0445\u045
 ConfigView.section.proxy.group.tracker=\u0417'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0437 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c
 ConfigView.section.proxy.group.peer=\u0417'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0437 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c\u0438
 Pieces.column.Requested=\u0417\u0430\u043f\u0438\u0442
-Pieces.column.Requested.info=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438, \u044f\u043a\u0449\u043e \u0431\u0456\u043b\u044c\u0448\u0435 \u0437\u0430\u043f\u0438\u0442\u0456\u0432 \u043c\u043e\u0433\u043b\u0438 \u0432\u0438\u043a\u043e\u043d\u0443\u0432\u0430\u0442\u0438\u0441\u044f \u0434\u043e \u0447\u0430\u0441\u0442\u0438\u043d\u0438 \u0430\u0431\u043e \u043d\u0456 (*)
-ConfigView.label.maxuploadsseeding=\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u043f\u0456\u0434 \u0447\u0430\u0441 \u043f\u043e\u0448\u0438\u0440\u0435\u043d\u043d\u044f
+Pieces.column.Requested.info=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438, \u0447\u0438 \u0431\u0456\u043b\u044c\u0448\u0435 \u0437\u0430\u043f\u0438\u0442\u0456\u0432 \u043c\u043e\u0433\u043b\u0438 \u0432\u0438\u043a\u043e\u043d\u0443\u0432\u0430\u0442\u0438\u0441\u044f \u0434\u043e \u0447\u0430\u0441\u0442\u0438\u043d\u0438 (*)
+ConfigView.label.maxuploadsseeding=\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u0438\u0439 \u0432\u0430\u0440\u0456\u0430\u043d\u0442 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 MyTorrentsView.filter=\u0424\u0456\u043b\u044c\u0442\u0440:
 popup.error.hideall=\u0421\u0445\u043e\u0432\u0430\u0442\u0438 \u0432\u0441\u0435
 ConfigView.section.style.dataStatsOnly=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u043e \u0434\u0430\u043d\u0438\u043c (\u043f\u0440\u0438\u0445\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443)
@@ -1823,45 +1823,45 @@ popup.closing.in=\u0412\u0456\u043a\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u
 popup.more.waiting=%1 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f(\u044c)..
 # > 2402
 popup.download.finished="%1" \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u0432 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.
-popup.file.finished="%1" \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0435.
+popup.file.finished="%1" \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0435.
 ConfigView.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e
 Plugin.localtracker.autoadd.info=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0434\u043e\u0434\u0430\u0432\u0430\u0442\u0438 \u0446\u0438\u0445 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0438\u0445 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 [';' \u0440\u043e\u0437\u0434\u0456\u043b\u0435\u043d\u0438\u0445 \u0430\u0434\u0440\u0435\u0441\u0430\u043c\u0438, \u0442\u043e\u0431\u0442\u043e, 1.2.3.4]
 Plugin.localtracker.autoadd=\u041e\u0441\u043e\u0431\u043b\u0438\u0432\u0456 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0438
-Plugin.localtracker.networks.info=\u0420\u043e\u0437\u0433\u043b\u044f\u0434\u0430\u0442\u0438 \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u0456 \u043c\u0435\u0440\u0435\u0436\u0456 \u044f\u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0456 [';' \u0440\u043e\u0437\u0434\u0456\u043b\u044f\u0442\u0438 \u043c\u0435\u0440\u0435\u0436\u0456, \u0442\u043e\u0431\u0442\u043e, 145.227.*.*]
+Plugin.localtracker.networks.info=\u0406\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0443\u0432\u0430\u0442\u0438 \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u0456 \u043c\u0435\u0440\u0435\u0436\u0456 \u044f\u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0456 [';' \u0440\u043e\u0437\u0434\u0456\u043b\u044f\u0442\u0438 \u043c\u0435\u0440\u0435\u0436\u0456, \u0442\u043e\u0431\u0442\u043e, 145.227.*.*]
 Plugin.localtracker.networks=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u0456 \u043c\u0435\u0440\u0435\u0436\u0456
-MainWindow.menu.view.plugins.logViews=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434 \u043b\u043e\u0433\u0456\u0432
+MainWindow.menu.view.plugins.logViews=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434 \u0444\u0430\u0439\u043b\u0456\u0432 .log
 SpeedView.stats.autospeed=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456
-SpeedView.stats.autospeed.disabled=\u0426\u044f \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c \u0442\u0435\u0436 \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u0430 (\u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0438\u0439 DHT), \u0430\u0431\u043e \u0457\u0457 \u043d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u043e \u0437\u0430\u0441\u0442\u043e\u0441\u0443\u0432\u0430\u0442\u0438 (\u043e\u0431\u0440\u0430\u043d\u0430 \u0440\u0443\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456)
+SpeedView.stats.autospeed.disabled=\u0426\u044f \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c \u0442\u0435\u0436 \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0430 (\u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0438\u0439 DHT), \u0430\u0431\u043e \u0457\u0457 \u043d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u043e \u0437\u0430\u0441\u0442\u043e\u0441\u0443\u0432\u0430\u0442\u0438 (\u0432\u0438\u0431\u0440\u0430\u043d\u0430 \u0440\u0443\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456)
 SpeedView.stats.idlePing=\u0412\u0456\u043b\u044c\u043d\u0438\u0439 \u043f\u0456\u043d\u0433:
 SpeedView.stats.maxPing=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u043f\u0456\u043d\u0433:
 SpeedView.stats.currentPing=\u041f\u043e\u0442\u043e\u0447\u043d\u0438\u0439 \u043f\u0456\u043d\u0433:
 SpeedView.stats.maxUp=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043c\u0435\u0436\u0430 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456:
 ConfigView.pluginlist.unloadSelected=\u0412\u0438\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043d\u0456
-ConfigView.pluginlist.scan=\u0421\u043a\u0430\u043d\u0443\u0432\u0430\u0442\u0438 \u043d\u0430 \u043d\u0430\u044f\u0432\u043d\u0456\u0441\u0442\u044c \u043d\u043e\u0432\u0438\u0445 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c
-ConfigView.section.transfer.autospeed=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c
-ConfigView.section.transfer.autospeed.tooltip=\u0414\u0435\u043a\u043e\u0442\u0440\u0456 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0457 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456
+ConfigView.pluginlist.scan=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u0438 \u043d\u0430\u044f\u0432\u043d\u0456\u0441\u0442\u044c \u043d\u043e\u0432\u0438\u0445 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c
+ConfigView.section.transfer.autospeed=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c (\u043a\u043b\u0430\u0441\u0438\u0447\u043d\u0430)
+ConfigView.section.transfer.autospeed.tooltip=\u0421\u043f\u0435\u0446\u0456\u0430\u043b\u044c\u043d\u0456 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0457 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456
 ConfigView.section.transfer.autospeed.info=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0440\u0435\u0433\u0443\u043b\u044e\u0454 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u0449\u043e\u0431 \u0443\u043d\u0438\u043a\u043d\u0443\u0442\u0438 \u043f\u0435\u0440\u0435\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f.\n\n\u0426\u0456 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u0434\u0443\u0442\u044c \u0437\u0430\u0441\u0442\u043e\u0441\u043e\u0432\u0430\u043d\u0456, \u043b\u0438\u0448\u0435 \u043a\u043e\u043b\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0430 \u0456 \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u0440\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u043e\u0457 \u0431\u0430\u0437\u0438 \u0434\u0430\u043d\u0438\u0445 \u0434\u043b\u044f \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u043d\u044f.\n
 ConfigView.section.transfer.autospeed.minupload=\u041c\u0456\u043d\u0456\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456, %1 
 ConfigView.section.transfer.autospeed.minupload.tooltip=\u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043d\u0435 \u0431\u0443\u0434\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0437\u043c\u0435\u043d\u0448\u0435\u043d\u0430 \u043d\u0438\u0436\u0447\u0435 \u0446\u044c\u043e\u0433\u043e \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f
 ConfigView.section.transfer.autospeed.maxupload=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456, %1 [0: \u043d\u0435 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
 ConfigView.section.transfer.autospeed.maxupload.tooltip=\u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043d\u0435 \u0431\u0443\u0434\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0437\u0431\u0456\u043b\u044c\u0448\u0435\u043d\u0430 \u0431\u0456\u043b\u044c\u0448\u0435 \u0446\u044c\u043e\u0433\u043e \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f
-ConfigView.section.transfer.autospeed.chokeping=\u0412\u0442\u0440\u0430\u0442\u0430 \u043f\u0430\u043a\u0435\u0442\u0456\u0432 [\u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434]
+ConfigView.section.transfer.autospeed.chokeping=\u0427\u0430\u0441 \u0437\u0430\u0442\u0443\u0445\u0430\u043d\u043d\u044f \u043f\u0456\u043d\u0433\u0443 [\u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434]
 ConfigView.section.transfer.autospeed.chokeping.tooltip=\u041d\u0430\u0434\u043b\u0438\u0448\u043e\u043a \u043f\u0456\u043d\u0433\u0443 \u0446\u044c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u0431\u0443\u0434\u0435 \u0432\u0432\u0430\u0436\u0430\u0442\u0438\u0441\u044f, \u044f\u043a \u0456\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043c\u0435\u0440\u0435\u0436\u0435\u0432\u043e\u0457 \u043d\u0430\u0441\u0438\u0447\u0435\u043d\u043e\u0441\u0442\u0456
 ConfigView.section.transfer.autospeed.enableauto=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438, \u043a\u043e\u043b\u0438 \u0442\u0440\u0438\u0432\u0430\u0454 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0430
 ConfigView.section.transfer.autospeed.enableautoseeding=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438, \u043b\u0438\u0448\u0435 \u043a\u043e\u043b\u0438 \u0442\u0440\u0438\u0432\u0430\u0454 \u0440\u043e\u0437\u0434\u0430\u0447\u0430
-ConfigView.pluginlist.column.unloadable=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0439
+ConfigView.pluginlist.column.unloadable=\u041d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0454\u0442\u044c\u0441\u044f
 ConfigView.section.transfer.lan.enable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043e\u043a\u0440\u0435\u043c\u0435 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0434\u043b\u044f \u0437'\u0454\u0434\u043d\u0430\u043d\u044c \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0456\u0439 \u043c\u0435\u0440\u0435\u0436\u0456
 Plugin.localtracker.wellknownlocals=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043c\u0456\u0441\u0442\u0438\u0442\u0438 \u0432 \u0441\u043e\u0431\u0456 \u043a\u043e\u043d\u0442\u0443\u0440 \u0437\u0432\u043e\u0440\u043e\u0442\u043d\u043e\u0433\u043e \u0437\u0432'\u044f\u0437\u043a\u0443/\u0437\u0432'\u044f\u0437\u043e\u043a/\u0441\u0430\u0439\u0442\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0438\u0445 \u043c\u0435\u0440\u0435\u0436 (192.168 \u0442\u043e\u0449\u043e)
 TableColumn.header.filesdone=\u0424\u0430\u0439\u043b\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456
 TableColumn.header.filesdone.info=\u0424\u0430\u0439\u043b\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456/\u0432\u0441\u044c\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0456\u0432 *\u0430\u0431\u043e* \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u0456 \u0444\u0430\u0439\u043b\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 (\u0444\u0430\u0439\u043b\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456)/\u0432\u0441\u044c\u043e\u0433\u043e \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u0438\u0445 \u0444\u0430\u0439\u043b\u0456\u0432 (\u0432\u0441\u044c\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0456\u0432)
 MagnetPlugin.private_torrent=<\u043e\u0441\u043e\u0431\u0438\u0441\u0442\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442>
-MagnetPlugin.decentral_disabled=<\u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0456\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0442\u0440\u0435\u043a\u0456\u043d\u0433 \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u0438\u0439>
-MagnetPlugin.decentral_backup_disabled=< \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0456\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0440\u0435\u0437\u0435\u0440\u0432 \u043a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043d\u044f \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u0438\u0439 >
-MagnetPlugin.report.waiting_ddb=\u0447\u0435\u043a\u0430\u0454 \u0434\u043b\u044f DDB-\u0456\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u0457...
+MagnetPlugin.decentral_disabled=<\u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0456\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0442\u0440\u0435\u043a\u0456\u043d\u0433 \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0438\u0439>
+MagnetPlugin.decentral_backup_disabled=< \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0456\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0440\u0435\u0437\u0435\u0440\u0432 \u043a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043d\u044f \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0438\u0439 >
+MagnetPlugin.report.waiting_ddb=\u0447\u0435\u043a\u0430\u0454 \u0434\u043b\u044f \u0456\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u0457 DDB...
 MagnetPlugin.report.searching=\u043f\u043e\u0448\u0443\u043a...
 MagnetPlugin.report.found=\u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e %1
-MagnetPlugin.report.alive=%1 \u0434\u0456\u044e\u0447\u0438\u0439
-MagnetPlugin.report.dead=%1 \u043d\u0435\u043f\u0440\u0430\u0446\u044e\u044e\u0447\u0438\u0439
+MagnetPlugin.report.alive=%1 \u0436\u0438\u0432\u0438\u0445
+MagnetPlugin.report.dead=%1 \u043c\u0435\u0440\u0442\u0432\u0438\u0445
 MagnetPlugin.report.tunnel=\u0442\u0443\u043d\u0435\u043b\u044e\u0432\u0430\u043d\u043d\u044f \u0432 %1
 MagnetPlugin.report.downloading=\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0454\u0442\u044c\u0441\u044f \u0437 %1
 MagnetPlugin.report.error=\u043f\u043e\u043c\u0438\u043b\u043a\u0430 %1
@@ -1872,25 +1872,25 @@ MagnetURLHandler.report.error=\u043f\u043e\u043c\u0438\u043b\u043a\u0430 %1
 DHTTransport.report.request_all=\u0437\u0430\u043f\u0438\u0442 \u043f\u043e\u0432\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437 %1
 DHTTransport.report.received_bit=\u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043e %1 \u0432 %2 \u0437 %3
 DHTTransport.report.complete=\u043a\u0456\u043d\u0435\u0446\u044c
-DHTTransport.report.timeout=\u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0447\u0430\u0441\u0443, \u043d\u0435\u043c\u0430\u0454 \u0432\u0456\u0434\u0433\u0443\u043a\u0456\u0432 \u0432\u0456\u0434 %1
+DHTTransport.report.timeout=\u0447\u0430\u0441 \u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f, \u043d\u0435\u043c\u0430 \u0432\u0456\u0434\u0433\u0443\u043a\u0456\u0432 \u0432\u0456\u0434 %1
 DHTTransport.report.rerequest_all=\u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0438\u0439 \u0437\u0430\u043f\u0438\u0442 \u043f\u043e\u0432\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437 %1
 DHTTransport.report.rerequest_bit=\u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0438\u0439 \u0437\u0430\u043f\u0438\u0442 %1 \u0432 %2 \u0437 %3
-DHTTransport.report.timeout_some=\u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0447\u0430\u0441\u0443, %1 \u043f\u0430\u043a\u0435\u0442\u0456\u0432 \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043e \u0432\u0456\u0434 %2, \u0430\u043b\u0435 \u0446\u0435 \u043d\u0435 \u043a\u0456\u043d\u0435\u0446\u044c
+DHTTransport.report.timeout_some=\u0447\u0430\u0441 \u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f, %1 \u043f\u0430\u043a\u0435\u0442\u0456\u0432 \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043e \u0432\u0456\u0434 %2, \u0430\u043b\u0435 \u0446\u0435 \u043d\u0435 \u043a\u0456\u043d\u0435\u0446\u044c
 DHTTransport.report.sending=\u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f \u0434\u0430\u043d\u0438\u0445
 DHTTransport.report.resending=\u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0435 \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f \u0434\u0430\u043d\u0438\u0445
 DHTTransport.report.send_complete=\u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u0435
-DHTTransport.report.send_timeout=\u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f \u0447\u0430\u0441\u0443
-ConfigView.section.transfer.autospeed.enabledebug=\u0417\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u0442\u0438 \u043b\u043e\u0433\u0438 \u043f\u043e\u043c\u0438\u043b\u043e\u043a \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0436\u0435\u043d\u043d\u044f
+DHTTransport.report.send_timeout=\u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f \u0447\u0430\u0441\u0443 \u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f
+ConfigView.section.transfer.autospeed.enabledebug=\u0417\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u0442\u0438 \u0432 .log \u043f\u043e\u043c\u0438\u043b\u043a\u0438 \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0436\u0435\u043d\u043d\u044f
 TableColumn.header.date_added=\u0414\u0430\u0442\u0430 \u0434\u043e\u0434\u0430\u0432\u0430\u043d\u043d\u044f
 TableColumn.header.date_added.info=\u0414\u0430\u0442\u0430 \u0434\u043e\u0434\u0430\u0432\u0430\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 ConfigView.section.file.hashchecking.smallestfirst=\u0421\u043f\u043e\u0447\u0430\u0442\u043a\u0443 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u0438 \u043d\u0430\u0439\u043c\u0435\u043d\u0448\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f 
-platform.win32.baddll.info=Vuze \u0432\u0438\u044f\u0432\u0438\u0432 \u043d\u0430\u044f\u0432\u043d\u0456\u0441\u0442\u044c '%1'. \u0426\u0435 \u0447\u0430\u0441\u0442\u0438\u043d\u0430 '%2' \u0456 \u043c\u043e\u0436\u0435 \u0432\u0438\u043a\u043b\u0438\u043a\u0430\u0442\u0438 \u0441\u0435\u0440\u0439\u043e\u0437\u043d\u0456 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438, \u0442\u0430\u043a\u0456 \u044f\u043a \u043a\u0440\u0430\u0445 \u0434\u043e\u0434\u0430\u0442\u043a\u0443 \u0456 \u0432\u0438\u0441\u043e\u043a\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u0426\u041f\u0423. \u042f\u043a\u0449\u043e \u0412\u0438 \u0437\u0456\u0448\u0442\u043e\u0432\u0445\u043d\u0435\u0448\u0441\u044f \u0437 \u043d\u0438\u043c\u0438, \u0442\u043e\u0434\u0456 \u0432\u0438\u0434\u0430\u043b\u0456\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u0430\u0431\u043e \u0457\u0445\u043d\u044e \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u044e, \u0449\u043e\u0431 \u043d\u0435 \u0437\u0456\u043f\u0441\u0443\u0432\u0430\u0442\u0438 Vuze.
+platform.win32.baddll.info=Vuze \u0432\u0438\u044f\u0432\u0438\u0432 \u043d\u0430\u044f\u0432\u043d\u0456\u0441\u0442\u044c '%1'. \u0426\u0435 \u0447\u0430\u0441\u0442\u0438\u043d\u0430 '%2' \u0456 \u043c\u043e\u0436\u0435 \u0432\u0438\u043a\u043b\u0438\u043a\u0430\u0442\u0438 \u0441\u0435\u0440\u0439\u043e\u0437\u043d\u0456 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438, \u0442\u0430\u043a\u0456 \u044f\u043a \u043a\u0440\u0430\u0445 \u0437\u0430\u0441\u0442\u043e\u0441\u0443\u043d\u043a\u0443 \u0456 \u0432\u0438\u0441\u043e\u043a\u0435 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u0426\u041f\u0423. \u042f\u043a\u0449\u043e \u0412\u0438 \u0437\u0456\u0448\u0442\u043e\u0432\u0445\u043d\u0435\u0448\u0441\u044f \u0437 \u043d\u0438\u043c\u0438, \u0442\u043e\u0434\u0456 \u0432\u0438\u043b\u0443\u0447\u0456\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u0430\u0431\u043e \u0457\u0445 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f, \u0449\u043e\u0431 \u043d\u0435 \u0437\u0456\u043f\u0441\u0443\u0432\u0430\u0442\u0438 Vuze.
 upnp.ignorebaddevices=\u0406\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u0438\u0441\u0442\u0440\u043e\u0457,  \u044f\u043a\u0456 \u0432\u0456\u0434\u043c\u043e\u0432\u043b\u044f\u044e\u0442\u044c\u0441\u044f \u0432\u0456\u0434\u043f\u043e\u0432\u0456\u0434\u0430\u0442\u0438 \u043a\u043e\u0440\u0435\u043a\u0442\u043d\u043e
 upnp.ignorebaddevices.info=\u041f\u043e\u0442\u043e\u0447\u043d\u0456 \u0456\u0433\u043d\u043e\u0440\u043e\u0432\u0430\u043d\u0456 \u043f\u0440\u0438\u0441\u0442\u0440\u043e\u0457: %1
 upnp.ignorebaddevices.reset=\u0421\u043a\u0438\u0434\u0430\u043d\u043d\u044f \u0441\u043f\u0438\u0441\u043a\u0443 \u0456\u0433\u043d\u043e\u0440\u043e\u0432\u0430\u043d\u0438\u0445 \u043f\u0440\u0438\u0441\u0442\u0440\u043e\u0457\u0432
 upnp.ignorebaddevices.reset.action=\u0421\u043a\u0438\u0434\u0430\u043d\u043d\u044f
 upnp.ignorebaddevices.alert=Upn-\u043f\u0440\u0438\u0441\u0442\u0440\u0456\u0439 \u043d\u0430 \u043c\u0456\u0441\u0446\u0456 %1 \u0431\u0443\u0432 \u0456\u0433\u043d\u043e\u0440\u043e\u0432\u0430\u043d\u0438\u0439 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0438\u043c\u0438 \u0432\u0456\u0434\u043c\u043e\u0432\u0430\u043c\u0438. \u041e\u0437\u043d\u0430\u0439\u043e\u043c\u0442\u0435\u0441\u044f \u0437 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u0454\u044e Upn-\u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c \u0434\u043b\u044f \u043e\u043f\u0446\u0456\u0439, \u044f\u043a\u0456 \u0432\u0456\u0434\u043d\u043e\u0441\u044f\u0442\u044c\u0441\u044f \u0434\u043e \u0434\u0456\u0457.
-TorrentOptionsView.param.max.uploads.when.busy=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u043a\u043e\u043b\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0435 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0434\u043e\u0441\u044f\u0433\u043d\u0443\u0442\u0435, \u041a\u0431\u0456\u0442/\u0441 [0: \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u0430]
+TorrentOptionsView.param.max.uploads.when.busy=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u043a\u043e\u043b\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0435 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0434\u043e\u0441\u044f\u0433\u043d\u0443\u0442\u0435, \u041a\u0431\u0456\u0442/\u0441 [0: \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0430]
 UpdateMonitor.messagebox.verification.failed.title=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u043d\u0435 \u043f\u0440\u043e\u0439\u0448\u043b\u043e \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438
 UpdateMonitor.messagebox.verification.failed.text=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 '%1' \u043d\u0435\u0432\u0434\u0430\u043b\u0430 : %2
 UpdateMonitor.messagebox.accept.unverified.title=\u0417\u0430\u0441\u0442\u043e\u0441\u0443\u0432\u0430\u0442\u0438 \u043d\u0435\u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0435\u043d\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
@@ -1900,38 +1900,38 @@ FileView.BlockView.Done=\u0412\u0438\u043a\u043e\u043d\u0430\u043d\u0438\u0445
 FileView.BlockView.Skipped=\u041f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u0438\u0445
 FileView.BlockView.Active=\u0410\u043a\u0442\u0438\u0432\u043d\u0438\u0445
 FileView.BlockView.Outstanding=\u041d\u0435\u0432\u0438\u043a\u043e\u043d\u0430\u043d\u0438\u0445
-ConfigView.label.tcplistenport=\u0412\u0445\u0456\u0434\u043d\u0438\u0439 TCP-\u043f\u043e\u0440\u0442 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f 
+ConfigView.label.tcplistenport=TCP-\u043f\u043e\u0440\u0442 \u0432\u0445\u0456\u0434\u043d\u0438\u0445 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c
 ConfigView.label.udplistenport=UDP-\u043f\u043e\u0440\u0442
 upnp.portchange.alert=\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u0456 \u043f\u043e\u0440\u0442\u0438 \u0437\u043c\u0456\u043d\u0435\u043d\u0456, \u0449\u043e\u0431 \u0443\u043d\u0438\u043a\u043d\u0443\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438 UPn -\u043f\u0440\u0438\u0441\u0442\u0440\u043e\u0457\u0432: %1 [\u0441\u0442\u0430\u0440\u0438\u0439 \u043f\u043e\u0440\u0442=%2] %3 [\u0441\u0442\u0430\u0440\u0438\u0439 \u043f\u043e\u0440\u0442=%4]
 ConfigView.section.proxy.username.info=\u042f\u043a\u0449\u043e \u043f\u0440\u043e\u043a\u0441\u0456-\u0441\u0435\u0440\u0432\u0435\u0440 \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0456\u0457, \u043d\u0430\u0432\u0456\u0442\u044c \u043a\u043e\u043b\u0438 \u043d\u0435 \u0432\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0439\u0442\u0435 \u0440\u044f\u0434\u043e\u043a "<none>" \u044f\u043a \u0406\u043c'\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430
 ConfigView.label.maxuploadswhenbusymin=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0443, \u043a\u043e\u043b\u0438 \u0437\u0430\u0439\u043d\u044f\u0442\u0438\u0439. \u0422\u0430\u0439\u043c\u0435\u0440, \u0441
 MainWindow.menu.help.debug=\u0413\u0435\u043d\u0435\u0440\u0443\u0432\u0430\u0442\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0436\u0435\u043d\u043d\u044f
 DownloadManager.error.badsize=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0438\u0439 \u0440\u043e\u0437\u043c\u0456\u0440
-natpmp.info=NAT-PMP \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 Apple \u0434\u043b\u044f UPn \u0456 \u0434\u043b\u044f \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0438 \u043e\u0441\u0442\u0430\u043d\u043d\u0456\u043c\u0438 \u0441\u0442\u0430\u043d\u0446\u0456\u044f\u043c\u0438 Airport \n\n\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430:  \u0437\u0430\u0440\u0430\u0437 UPn \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0435, \u0432\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438\u0439 NAT-PMP \u044f\u043a NAT-PMP-\u043f\u0440\u0438\u0441\u0442\u0440\u0456\u0439 \u0440\u043e\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u0438\u0439 \u044f\u043a \u043e\u0441\u043e\u0431\u043b\u0438\u0432\u0438\u0439 \u0442\u0438\u043f\u0443 Upn-\u043f\u0440\u0438\u0441\u0442\u0440\u043e\u044e
-natpmp.enable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 (\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430:  \u0442\u0430\u043a\u043e\u0436 \u043d\u0435 \u043f\u043e\u0432\u0438\u043d\u043d\u0438\u0439 \u0431\u0443\u0442\u0438 \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u043c \u0443 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u0457 Airport, \u0449\u043e\u0431 \u043f\u0440\u0430\u0446\u044e\u0432\u0430\u0442\u0438)
-ConfigView.section.tracker.host.addurls=\u0417\u0430\u0431\u0435\u0437\u043f\u0435\u0447\u0438\u0442\u0438 \u043b\u0456\u043d\u043a\u0438 \u0442\u0440\u0435\u043a\u0435\u0440\u0443, \u0456\u0441\u043d\u0443\u044e\u0447\u0456 \u0432 \u0433\u043e\u043b\u043e\u0432\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0430\u0445
+natpmp.info=NAT-PMP - \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 Apple \u0434\u043b\u044f UPn\u0420 \u0456 \u0434\u043b\u044f \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0438 \u043e\u0441\u0442\u0430\u043d\u043d\u0456\u043c\u0438 \u0441\u0442\u0430\u043d\u0446\u0456\u044f\u043c\u0438 Airport \n\n\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430:  \u0437\u0430\u0440\u0430\u0437 UPn \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0435, \u0432\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438\u0439 NAT-PMP \u044f\u043a \u043d\u043e\u0441\u0456\u0439 NAT-PMP \u0440\u043e\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u0438\u0439 \u044f\u043a \u043e\u0441\u043e\u0431\u043b\u0438\u0432\u0438\u0439 \u0442\u0438\u043f \u043d\u043e\u0441\u0456\u044f Upn
+natpmp.enable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 (\u041f\u0440\u0438\u043c\u0456\u0442\u043a\u0430:  \u0442\u0430\u043a\u043e\u0436 \u043f\u043e\u0432\u0438\u043d\u043d\u0438\u0439 \u0431\u0443\u0442\u0438 \u0432\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u043c \u0443 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u0457 Airport, \u0449\u043e\u0431 \u043f\u0440\u0430\u0446\u044e\u0432\u0430\u0442\u0438)
+ConfigView.section.tracker.host.addurls=\u0412\u043f\u0435\u0432\u043d\u0438\u0442\u0438\u0441\u044f, \u0449\u043e \u043b\u0456\u043d\u043a\u0438 \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u043d\u0430\u044f\u0432\u043d\u0456 \u0432 \u0442\u043e\u0440\u0435\u043d\u0442\u0430\u0445, \u044f\u043a\u0456 \u043f\u0440\u0438\u0439\u043c\u0430\u044e\u0442\u044c\u0441\u044f
 ConfigView.filter=\u0444\u0456\u043b\u044c\u0442\u0440
-ConfigView.section.files.move=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f \u043f\u0435\u0440\u0435\u043c\u0456\u0449\u0435\u043d\u043d\u044f
+ConfigView.section.files.move=\u041f\u0435\u0440\u0435\u043c\u0456\u0449\u0435\u043d\u043d\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0438\u0445
 ConfigView.section.file.defaultdir.section=\u041e\u043f\u0446\u0456\u0457 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0457 \u0442\u0435\u043a\u0438
 ConfigView.section.file.defaultdir.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443 \u0442\u0435\u043a\u0443 (\u0431\u0435\u0437 \u0448\u043b\u044f\u0445\u0443)
-ConfigView.section.file.defaultdir.bestguess=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u043a\u0440\u0430\u0449\u0435 \u043f\u0440\u0438\u043f\u0443\u0449\u0435\u043d\u043d\u044f \u043f\u0440\u0438 \u0432\u0438\u0431\u043e\u0440\u0456 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0457 \u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
+ConfigView.section.file.defaultdir.bestguess=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u043a\u0440\u0430\u0449\u0438\u0439 \u0432\u0430\u0440\u0456\u0430\u043d\u0442 \u043f\u0440\u0438 \u0432\u0438\u0431\u043e\u0440\u0456 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0457 \u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
 ConfigView.section.file.defaultdir.ask=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430 \u0442\u0435\u043a\u0430:
 ConfigView.section.file.defaultdir.lastused=\u0417\u043c\u0456\u043d\u0438\u0442\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443 \u0442\u0435\u043a\u0443 \u0434\u043b\u044f \u0440\u043e\u0437\u043c\u0456\u0449\u0435\u043d\u043d\u044f \u043e\u0441\u0442\u0430\u043d\u043d\u044c\u043e\u0433\u043e \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
 ConfigView.section.file.config.section=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u0457
 ConfigView.section.file.config.currentdir=\u041f\u043e\u0442\u043e\u0447\u043d\u0430 \u0442\u0435\u043a\u0430 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u0457:
-ConfigView.section.torrent.decoding=\u0414\u0435\u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0430\u0431\u043e\u0440\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u0456\u0432
+ConfigView.section.torrent.decoding=\u0414\u0435\u043a\u043e\u0434\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0430\u0431\u043e\u0440\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u0456\u0432
 ConfigView.section.logging.udptransport=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0434\u043e\u043a\u043b\u0430\u0434\u043d\u0435 \u0442\u0440\u0430\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0456 UDP
 Tracker.announce.ignorePeerSeed=\u0406\u0433\u043d\u043e\u0440\u0443\u0432\u0430\u0442\u0438 \u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0434\u043e \u0441\u0456\u0434\u0435\u0440\u0456\u0432. %1
-ConfigView.section.connection.encryption.use_crypto_port=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043f\u043e\u0440\u0442 \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430, \u0449\u043e\u0431 \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u0438 \u043f\u0440\u044f\u043c\u0438\u0445 \u0432\u0445\u0456\u0434\u043d\u0438\u0445 \u0441\u043f\u0440\u043e\u0431 \u0437\u2019\u0454\u0434\u043d\u0430\u043d\u043d\u044f. \n\n\u0414\u0435\u044f\u043a\u0456 \u0442\u0440\u0435\u043a\u0435\u0440\u0438 \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u044c \u0446\u044c\u043e\u0433\u043e \u0456 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u044f\u044e\u0442\u044c  \u043f\u043e\u043c\u0438\u043b\u043a\u0438,  \u0442\u0430\u043a\u0456 \u044f\u043a "\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0438\u0439 \u041f\u043e\u0440\u0442" \u0430\u0431\u043e "\u041d\u0435\u043f\u0440\u0438\u043f\u0443\u0441\u0442\u0438\u043c\u0438\u0439 \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440"
+ConfigView.section.connection.encryption.use_crypto_port=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043f\u043e\u0440\u0442 \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430, \u0449\u043e\u0431 \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u0438 \u043f\u0440\u044f\u043c\u0438\u0445 \u0432\u0445\u0456\u0434\u043d\u0438\u0445 \u0441\u043f\u0440\u043e\u0431 \u0437\u2019\u0454\u0434\u043d\u0430\u043d\u043d\u044f. \n\n\u0414\u0435\u044f\u043a\u0456 \u0442\u0440\u0435\u043a\u0435\u0440\u0438 \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u044c \u0446\u044c\u043e\u0433\u043e \u0456 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u044f\u044e\u0442\u044c \u043f\u0440\u043e \u0442\u0430\u043a\u0456 \u043f\u043e\u043c\u0438\u043b\u043a\u0438, \u044f\u043a "\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0438\u0439 \u043f\u043e\u0440\u0442" \u0430\u0431\u043e "\u041d\u0435\u043f\u0440\u0438\u043f\u0443\u0441\u0442\u0438\u043c\u0438\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440"
 TorrentOptionsView.param.reset.to.default=\u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438 \u043f\u043e\u0447\u0430\u0442\u043a\u043e\u0432\u0456 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438
 TorrentOptionsView.param.reset.button=\u0421\u043a\u0438\u043d\u0443\u0442\u0438
 natpmp.routeraddress=\u0410\u0434\u0440\u0435\u0441\u0430 \u0441\u0442\u0430\u043d\u0446\u0456\u0457 [\u043f\u043e\u0440\u043e\u0436\u043d\u0454: \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e]
-ConfigView.section.style.disableAlertSliding=\u0412\u0438\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u043b\u0430\u0432\u043d\u0443 \u0430\u043d\u0456\u043c\u0430\u0446\u0456\u044e \u0456 \u0440\u0435\u0436\u0438\u043c '\u0437\u0432\u0435\u0440\u0445\u0443 \u0432\u0441\u0456\u0445' \u0434\u043b\u044f \u0432\u0438\u0440\u0438\u043d\u0430\u044e\u0447\u0438\u0445 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c
+ConfigView.section.style.disableAlertSliding=\u0412\u0438\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u043b\u0430\u0432\u043d\u0443 \u0430\u043d\u0456\u043c\u0430\u0446\u0456\u044e \u0456 \u0440\u0435\u0436\u0438\u043c '\u0437\u0433\u043e\u0440\u0438 \u0432\u0441\u0456\u0445' \u0434\u043b\u044f \u0432\u0438\u0440\u0438\u043d\u0430\u044e\u0447\u0438\u0445 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c
 ConfigView.section.transfer.autospeed.maxinc=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0435 \u0437\u0431\u0456\u043b\u044c\u0448\u0435\u043d\u043d\u044f \u043d\u0430 \u0446\u0438\u043a\u043b, %1 
 ConfigView.section.transfer.autospeed.maxdec=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0435 \u0437\u043c\u0435\u043d\u0448\u0435\u043d\u043d\u044f \u043d\u0430 \u0446\u0438\u043a\u043b, %1 
 ConfigView.section.transfer.autospeed.enabledownadj=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043a\u043e\u0440\u0435\u043a\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 ConfigView.section.transfer.autospeed.downadjratio=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f : \u041a\u043e\u0435\u0444\u0456\u0446\u0456\u0454\u043d\u0442 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456\n(\u0442\u043e\u0431\u0442\u043e, 2.0 - \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0432\u0434\u0432\u0456\u0447\u0456\n\u0431\u0456\u043b\u044c\u0448\u0435 \u0437\u0430 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456)
-ConfigView.section.transfer.autospeed.latencyfactor=\u041f\u043e\u043a\u0430\u0437\u043d\u0438\u043a \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u043f\u0456\u043d\u0433\u0443 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0434\u043b\u044f \u0437\u043c\u0456\u043d\u0438 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456\n(\u0431\u0456\u043b\u044c\u0448\u0435 \u0447\u0438\u0441\u043b\u043e \u0437\u043c\u0435\u043d\u0448\u0443\u0454 \u0447\u0443\u0442\u043b\u0438\u0432\u0456\u0441\u0442\u044c)
+ConfigView.section.transfer.autospeed.latencyfactor=\u041f\u043e\u043a\u0430\u0437\u043d\u0438\u043a \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u0437\u043c\u0456\u043d\u0438 \u043b\u0430\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0456 \u043c\u0435\u0440\u0435\u0436\u0456 \u0434\u043b\u044f \u0437\u043c\u0456\u043d\u0438 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456\n(\u0431\u0456\u043b\u044c\u0448\u0435 \u0447\u0438\u0441\u043b\u043e \u0437\u043c\u0435\u043d\u0448\u0443\u0454 \u0447\u0443\u0442\u043b\u0438\u0432\u0456\u0441\u0442\u044c)
 ConfigView.section.transfer.autospeed.reset=\u0421\u043a\u0438\u0434\u0430\u043d\u043d\u044f \u0440\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u044c
 ConfigView.section.transfer.autospeed.reset.button=\u0421\u043a\u0438\u043d\u0443\u0442\u0438
 PeerColumn.activationCount=\u0423\u0447\u0430\u0441\u043d\u0438\u043a\u0438 \u043d\u0430\u043c\u0430\u0433\u0430\u044e\u0442\u044c\u0441\u044f \u0437'\u0454\u0434\u043d\u0430\u0442\u0438\u0441\u044f: %1
@@ -1945,7 +1945,7 @@ PeersView.outgoingreqcount=\u0412\u0438\u0445\u0456\u0434\u043d\u0456 \u0437\u04
 PeersView.outgoingreqcount.info=\u041f\u0456\u0434\u0440\u0430\u0445\u0443\u043d\u043e\u043a \u0432\u0438\u0445\u0456\u0434\u043d\u0438\u0445 \u0437\u0430\u043f\u0438\u0442\u0456\u0432, \u0437\u0440\u043e\u0431\u043b\u0435\u043d\u0438\u0445 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u043e\u043c
 upnp.mapping.trackerclientudp=\u041f\u043e\u0440\u0442 \u043a\u043b\u0456\u0454\u043d\u0442\u0430 UDP-\u0442\u0440\u0435\u043a\u0435\u0440\u0443
 upnp.mapping.dhtudp=\u0420\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u0430 \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u0438\u0445
-ConfigView.section.connection.nondata.udp.same=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0442\u0438 \u0442\u043e\u0439 \u0436\u0435 UDP-\u043f\u043e\u0440\u0442 \u0434\u043b\u044f \u0440\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u043e\u0457 \u0431\u0430\u0437\u0438 \u0434\u0430\u043d\u0438\u0445 \u0456 UDP-\u0442\u0440\u0435\u043a\u0435\u0440\u0443
+ConfigView.section.connection.nondata.udp.same=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043e\u0434\u0438\u043d UDP-\u043f\u043e\u0440\u0442 \u0434\u043b\u044f \u0440\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u043e\u0457 \u0431\u0430\u0437\u0438 \u0434\u0430\u043d\u0438\u0445 \u0456 UDP-\u0442\u0440\u0435\u043a\u0435\u0440\u0443
 ConfigView.section.connection.tcp.enable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 TCP
 ConfigView.section.connection.udp.enable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 UDP
 ConfigView.section.style.showiconbar=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u0456\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0456\u0432
@@ -1955,11 +1955,11 @@ MyTorrentsView.menu.rename.displayed=\u041f\u0435\u0440\u0435\u0439\u043c\u0435\
 MyTorrentsView.menu.rename.save_path=\u041f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0438 \u0448\u043b\u044f\u0445 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
 MyTorrentsView.menu.rename.displayed_and_save_path=\u041f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0438 \u043e\u0431\u0438\u0434\u0432\u0430
 MyTorrentsView.menu.rename.displayed.enter.title=\u041f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0438 \u0432\u043a\u0430\u0437\u0430\u043d\u0435 \u0456\u043c'\u044f
-MyTorrentsView.menu.rename.displayed.enter.message=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043d\u043e\u0432\u0435 \u0456\u043c'\u044f, \u044f\u043a\u0435 \u0434\u0456\u044f\u0442\u0438\u043c\u0435 \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.\n\u042f\u043a\u0449\u043e \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0432\u043a\u0430\u0437\u0430\u043d\u0438\u0439, \u0434\u0456\u044f\u0442\u0438\u043c\u0435 \u043e\u0440\u0438\u0433\u0456\u043d\u0430\u043b\u044c\u043d\u0435 \u0456\u043c'\u044f.
+MyTorrentsView.menu.rename.displayed.enter.message=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043d\u043e\u0432\u0435 \u0456\u043c'\u044f, \u044f\u043a\u0435 \u0434\u0456\u044f\u0442\u0438\u043c\u0435 \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.
 MyTorrentsView.menu.rename.save_path.enter.title=\u041f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0438 \u0448\u043b\u044f\u0445 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f
-MyTorrentsView.menu.rename.save_path.enter.message=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043d\u043e\u0432\u0435 \u043c\u0456\u0441\u0446\u0435 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f .\n\u042f\u043a\u0449\u043e \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0432\u043a\u0430\u0437\u0430\u043d\u0438\u0439, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u043c\u0435\u0442\u044c\u0441\u044f \u0446\u0435 \u0456\u043c'\u044f.
+MyTorrentsView.menu.rename.save_path.enter.message=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043d\u043e\u0432\u0435 \u0440\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f .
 MyTorrentsView.menu.rename.displayed_and_save_path.enter.title=\u041f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
-MyTorrentsView.menu.rename.displayed_and_save_path.enter.message=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043d\u043e\u0432\u0435 \u0456\u043c'\u044f \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f\n\u042f\u043a\u0449\u043e \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0432\u043a\u0430\u0437\u0430\u043d\u0438\u0439, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u043c\u0435\u0442\u044c\u0441\u044f \u043e\u0440\u0438\u0433\u0456\u043d\u0430\u043b\u044c\u043d\u0456 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f.
+MyTorrentsView.menu.rename.displayed_and_save_path.enter.message=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043d\u043e\u0432\u0435 \u0456\u043c'\u044f \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 MyTorrentsView.menu.edit_comment=\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440
 MyTorrentsView.menu.edit_comment.enter.title=\u0420\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440
 MyTorrentsView.menu.edit_comment.enter.message=\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u0438 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440 \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.
@@ -1969,20 +1969,20 @@ UIDebugGenerator.complete.title=\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0456
 UIDebugGenerator.complete.text=\u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u0442\u0435 \u0444\u0430\u0439\u043b '%1' \u043d\u0430 az-bugreports at azureus-inc.com\n\n\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c O\u041a, \u0449\u043e\u0431 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0446\u0435\u0439 \u0444\u0430\u0439\u043b \u0432 \u0432\u0456\u043a\u043d\u0456.
 ConfigView.section.style.showProgramIcon=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u0432 \u043d\u0430\u0437\u0432\u0456 \u0441\u0442\u043e\u0432\u043f\u0446\u044f
 ConfigView.section.style.showProgramIcon.tooltip=\u0412\u0438\u0433\u043b\u044f\u0434 \u043c\u043e\u0436\u0435 \u0432\u0438\u043c\u0430\u0433\u0430\u0442\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0442\u044f \u0434\u043b\u044f \u0437\u0430\u0441\u0442\u043e\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u043c\u0456\u043d
-swt.alert.cant.update=SWT-\u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0430, \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0430 \u0437 "%3" \u043d\u0435 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u0437 \u0432\u0435\u0440\u0441\u0456\u0457 %1 \u0434\u043e %2 (\u043f\u043e\u0432\u0438\u043d\u043d\u0430 \u0431\u0443\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0430 \u0437 "%4"). \u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0432\u0456\u0434\u0432\u0456\u0434\u0430\u0439\u0442\u0435 <A HREF="http://azureus.aelitis.com/wiki/index.php/SWT_Cant_Auto_Update">Wiki-\u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443</A> \u0434\u043b\u044f \u0434\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457.
+swt.alert.cant.update=SWT-\u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0430, \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0430 \u0437 "%3" \u043d\u0435 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u0437 \u0432\u0435\u0440\u0441\u0456\u0457 %1 \u0434\u043e %2 (\u043f\u043e\u0432\u0438\u043d\u043d\u0430 \u0431\u0443\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0430 \u0437 "%4"). \u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0432\u0456\u0434\u0432\u0456\u0434\u0430\u0439\u0442\u0435 <A HREF="http://wiki.vuze.com/index.php/SWT_Cant_Auto_Update">Wiki-\u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443</A> \u0434\u043b\u044f \u0434\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457.
 authenticator.savepassword=\u0417\u0430\u043f\u0430\u043c'\u044f\u0442\u0430\u0442\u0438 \u043c\u0456\u0439 \u043f\u0430\u0440\u043e\u043b\u044c
-ConfigView.section.security.clearpasswords=\u0421\u043a\u0438\u0434\u0430\u043d\u043d\u044f \u043f\u0430\u0440\u043e\u043b\u0456\u0432
+ConfigView.section.security.clearpasswords=\u0421\u043a\u0438\u0434\u0430\u043d\u043d\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0438\u0445 \u043f\u0430\u0440\u043e\u043b\u0456\u0432
 ConfigView.section.security.clearpasswords.button=\u0421\u043a\u0438\u043d\u0443\u0442\u0438
 Content.alert.notuploaded.title=\u0420\u043e\u0437\u0434\u0430\u0447\u0456 \u043d\u0435 \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0456
 Content.alert.notuploaded.text=\u0420\u043e\u0437\u0434\u0430\u0447\u0430 '%1' \u043d\u0435 \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u043b\u0430\u0441\u044f. \u042f\u043a\u0449\u043e \u0412\u0438 %2 \u0437\u0430\u0440\u0430\u0437, \u043b\u044e\u0434\u0438 \u043d\u0435 \u0437\u043c\u043e\u0436\u0443\u0442\u044c \u043f\u043e\u0432\u043d\u0456\u0441\u0442\u044e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0432\u0430\u0448\u0443 \u043e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u0443 \u0440\u043e\u0431\u043e\u0442\u0443.\n\n\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 %2?
 Content.alert.notuploaded.multi.title=\u0420\u043e\u0437\u0434\u0430\u0447\u0456 \u043d\u0435 \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0456
-Content.alert.notuploaded.multi.text=%1 \u0432\u0430\u0448\u043e\u0433\u043e \u043e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u043e\u0433\u043e \u0432\u043c\u0456\u0441\u0442\u0443 \u043d\u0435 \u0432\u0456\u0434\u0434\u0430\u043d\u043e. \u042f\u043a\u0449\u043e \u0412\u0438 %2 \u0437\u0430\u0440\u0430\u0437, \u043b\u044e\u0434\u0438 \u043d\u0435 \u0437\u043c\u043e\u0436\u0443\u0442\u044c \u043f\u043e\u0432\u043d\u0456\u0441\u0442\u044e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0432\u0430\u0448\u0443 \u043e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u0443 \u0440\u043e\u0431\u043e\u0442\u0443. \u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 %2?\n\n\u0412\u043c\u0456\u0441\u0442 \u043d\u0435 \u0440\u043e\u0437\u0434\u0430\u043d\u0438\u0439 \u043f\u043e\u0432\u043d\u0456\u0441\u0442\u044e:\n%3
+Content.alert.notuploaded.multi.text=%1 \u0432\u0430\u0448\u043e\u0457 \u043e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u043d\u0435 \u0432\u0456\u0434\u0434\u0430\u043d\u043e. \u042f\u043a\u0449\u043e \u0412\u0438 %2 \u0437\u0430\u0440\u0430\u0437, \u043b\u044e\u0434\u0438 \u043d\u0435 \u0437\u043c\u043e\u0436\u0443\u0442\u044c \u043f\u043e\u0432\u043d\u0456\u0441\u0442\u044e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0432\u0430\u0448\u0443 \u043e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u0443 \u0440\u043e\u0431\u043e\u0442\u0443. \u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 %2?\n\n\u0406\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u0440\u043e\u0437\u0434\u0430\u043d\u0430 \u043d\u0435 \u043f\u043e\u0432\u043d\u0456\u0441\u0442\u044e:\n%3
 Content.alert.notuploaded.stop=\u0437\u0443\u043f\u0438\u043d\u0438\u0442\u0438
 Content.alert.notuploaded.quit=\u0432\u0438\u0439\u0442\u0438
 TorrentInfoView.torrent.encoding=\u0428\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 TorrentInfoView.columns=\u0421\u0442\u043e\u0432\u043f\u0447\u0438\u043a\u0438 \u0437 \u0432\u0438\u0433\u043b\u044f\u0434\u0443 '\u041c\u043e\u0457 \u0422\u043e\u0440\u0435\u043d\u0442\u0438' 
 progress.window.title=\u0422\u0440\u0438\u0432\u0430\u0454
-progress.window.msg.filemove=\u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0437\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435, \u0434\u043e\u043a\u0438 \u0444\u0430\u0439\u043b \u043f\u043e\u0432\u043d\u0456\u0441\u0442\u044e \u043f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0430\u0431\u043e \u043f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0454\u0442\u044c\u0441\u044f
+progress.window.msg.filemove=\u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0437\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435, \u043f\u043e\u043a\u0438 \u0444\u0430\u0439\u043b \u043f\u043e\u0432\u043d\u0456\u0441\u0442\u044e \u043f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0430\u0431\u043e \u043f\u0435\u0440\u0435\u0439\u043c\u0435\u043d\u0443\u0454\u0442\u044c\u0441\u044f
 ConfigView.label.popup.timestamp=\u0414\u043e\u0434\u0430\u0442\u0438 \u0442\u0430\u0439\u043c\u0435\u0440 \u0432\u0438\u0440\u0438\u043d\u0430\u044e\u0447\u043e\u0433\u043e \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f
 ConfigView.label.popup.autohide=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0440\u0438\u0445\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0441\u0435\u0440\u0432\u0456\u0441\u043d\u0456 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u043f\u0456\u0441\u043b\u044f x \u0441\u0435\u043a\u0443\u043d\u0434 (0 \u0434\u043b\u044f \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u0445\u043e\u0432\u0443\u0432\u0430\u043d\u043d\u044f) 
 ConfigView.label.popup.suppress_alerts=\u041f\u0440\u0438\u0441\u0456\u043a\u0442\u0438 \u0442\u0440\u0438\u0432\u043e\u0433\u0438
@@ -1991,48 +1991,48 @@ ConfigView.label.popup.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0
 ConfigView.label.popup.show.button=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438
 ConfigView.label.please.visit.here=\u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0432\u0456\u0434\u0432\u0456\u0434\u0430\u0439\u0442\u0435 \u0446\u0435 \u0434\u043b\u044f \u0434\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457
 ConfigView.section.ipfilter.enable.descriptionCache=\u0417\u0430\u043f\u0430\u043c'\u044f\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043e\u043f\u0438\u0441 IP \u0432 \u0442\u0438\u043c\u0447\u0430\u0441\u043e\u0432\u043e\u043c\u0443 \u0444\u0430\u0439\u043b\u0456
-ConfigView.section.ipfilter.enable.descriptionCache.tooltip=\u041a\u043e\u043b\u0438 \u043e\u043f\u0446\u0456\u044f \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u0430, \u043e\u043f\u0438\u0441\u0438 \u043d\u0435 \u0437\u0430\u043f\u0430\u043c'\u044f\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u043c\u0443\u0442\u044c\u0441\u044f
+ConfigView.section.ipfilter.enable.descriptionCache.tooltip=\u041a\u043e\u043b\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0438\u0439, \u043e\u043f\u0438\u0441\u0438 \u043d\u0435 \u0437\u0430\u043f\u0430\u043c'\u044f\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u043c\u0443\u0442\u044c\u0441\u044f
 OpenTorrentWindow.filesInfo=%1 \u0437 %2 \u0431\u0443\u0434\u0443\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456.
 OpenTorrentWindow.diskUsage=%1 \u0437 %2
 ConfigView.label.openmytorrents=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 '\u041c\u043e\u0457 \u0442\u043e\u0440\u0435\u043d\u0442\u0438' \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0443
 ConfigView.label.open_transfer_bar_on_start=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443
 ConfigView.section.style.DNDalwaysInIncomplete=\u0417\u0430\u0432\u0436\u0434\u0438 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0437 '\u043d\u0435\u0434\u043e\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u043c\u0438' \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0432 \u0440\u043e\u0437\u0434\u0456\u043b\u0456 \u043d\u0435\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0445 '\u041c\u043e\u0457\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432'
-OpenTorrentWindow.mb.noGlobalDestDir.title=\u0422\u0435\u043a\u0430 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u0430
+OpenTorrentWindow.mb.noGlobalDestDir.title=\u0422\u0435\u043a\u0430 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f
 OpenTorrentWindow.mb.noGlobalDestDir.text=\u0422\u0435\u043a\u0430 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f '%1' \u043d\u0435 \u0456\u0441\u043d\u0443\u0454 \u0430\u0431\u043e \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430.
 OpenTorrentWindow.mb.noDestDir.title=\u0422\u0435\u043a\u0430 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u0430
 OpenTorrentWindow.mb.noDestDir.text=\u0422\u0435\u043a\u0430 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f '%1' \u0434\u043b\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443 '%2' \u043d\u0435 \u0456\u0441\u043d\u0443\u0454 \u0430\u0431\u043e \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430.
 OpenTorrentWindow.mb.notValid.title=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442
-OpenTorrentWindow.mb.notValid.text=\u041d\u0435 \u043c\u043e\u0436\u0443 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 '%1'. \u042f\u043a\u0449\u043e \u0412\u0438 \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0454\u0442\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u043f\u0435\u0440\u0435\u043a\u043e\u043d\u0430\u0439\u0442\u0435\u0441\u044f, \u0449\u043e \u0432\u0456\u0434\u043e\u043c\u043e\u0441\u0442\u0456 \u043f\u0440\u043e \u0444\u0430\u0439\u043b\u0438-\u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0456\u0441\u043d\u0443\u044e\u0442\u044c.
+OpenTorrentWindow.mb.notValid.text=\u041d\u0435 \u043c\u043e\u0436\u0443 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 '%1'. \u042f\u043a\u0449\u043e \u0412\u0438 \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0454\u0442\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u043f\u0435\u0440\u0435\u043a\u043e\u043d\u0430\u0439\u0442\u0435\u0441\u044f, \u0449\u043e \u0444\u0430\u0439\u043b\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0443 \u0456\u0441\u043d\u0443\u044e\u0442\u044c.
 OpenTorrentWindow.mb.notTorrent.title=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442
 OpenTorrentWindow.mb.notTorrent.text=\u041d\u0435 \u043c\u043e\u0436\u0443 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438 '%1'. \u0412\u0456\u043d \u043d\u0435 \u0437'\u044f\u0432\u043b\u044f\u0454\u0442\u044c\u0441\u044f \u0443 \u0432\u0438\u0433\u043b\u044f\u0434\u0456 \u0442\u043e\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b\u0443.\n\n\u0414\u0435\u044f\u043a\u0456 \u0434\u0430\u043d\u0456 \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u0456:\n%2
 ConfigView.label.pause.downloads.on.exit=\u0417\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u043f\u0440\u0438 \u0437\u0430\u043a\u0440\u0438\u0442\u0442\u0456
-ConfigView.label.resume.downloads.on.start=\u0412\u0456\u0434\u043d\u043e\u0432\u0438\u0442\u0438 \u0437\u0443\u043f\u0438\u043d\u0435\u043d\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
+ConfigView.label.resume.downloads.on.start=\u0412\u0456\u0434\u043d\u043e\u0432\u0438\u0442\u0438 \u0437\u0443\u043f\u0438\u043d\u0435\u043d\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0456\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u0457
 UIDebugGenerator.message.cancel.title=\u0417\u0431\u0456\u0440 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0436\u0435\u043d\u043d\u044f \u0441\u043a\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u0439
 UIDebugGenerator.message.cancel.text=\u0412\u0438 \u043d\u0435 \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u043e\u043c\u0438\u043b\u043a\u0443, \u043f\u0440\u043e \u044f\u043a\u0443 \u0412\u0438 \u043d\u0430\u043c\u0430\u0433\u0430\u0454\u0442\u0435\u0441\u044f \u0440\u043e\u0437\u043f\u043e\u0432\u0456\u0441\u0442\u0438. \u0412\u0430\u0448\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u044e \u0434\u043b\u044f \u0412\u0430\u0441, \u0430\u043b\u0435 \u0431\u0435\u0437 \u043e\u043f\u0438\u0441\u0443 \u043c\u0438 \u0437\u043c\u043e\u0436\u0435\u043c\u043e \u043b\u0438\u0448\u0435 \u043b\u0430\u043c\u0430\u0442\u0438 \u0433\u043e\u043b\u043e\u0432\u0443, \u0432 \u0447\u043e\u043c\u0443 \u0436  \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430.\n\n\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0456\u044f \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0436\u0435\u043d\u043d\u044f \u0441\u043a\u0430\u0441\u043e\u0432\u0430\u043d\u0430.
 ConfigView.section.connection.group.http.info=\u041f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0430 HTTP-\u0440\u043e\u0437\u0434\u0430\u0447\u0456.
 ConfigView.section.connection.http.enable=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438
-ConfigView.section.connection.http.port=\u041d\u043e\u043c\u0435\u0440 \u0432\u0445\u0456\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0443
-ConfigView.section.connection.http.portoverride=\u0417\u0430\u043c\u0456\u043d\u0438\u0442\u0438 \u043f\u043e\u0440\u0442 HTTP-\u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u043d\u0430 [0: \u043d\u0456\u044f\u043a\u0438\u0439]
+ConfigView.section.connection.http.port=\u041d\u043e\u043c\u0435\u0440 \u043f\u043e\u0440\u0442\u0443 \u0432\u0445\u0456\u0434\u043d\u0438\u0445 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c
+ConfigView.section.connection.http.portoverride=\u0417\u0430\u043c\u0456\u043d\u0438\u0442\u0438 HTTP-\u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u043d\u0430 [0: \u043d\u0456\u044f\u043a\u0438\u0439]
 window.update.noupdates.title=\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0438 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0438 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c
-window.update.noupdates.text=\u041d\u0435\u043c\u0430\u0454 \u043d\u043e\u0432\u0438\u0445 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c.\n\n\u0412\u0456\u0442\u0430\u0454\u043c\u043e!
+window.update.noupdates.text=\u041d\u0435\u043c\u0430 \u043d\u043e\u0432\u0438\u0445 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u044c.\n\n
 ConfigView.label.bindip.details=\u0414\u043b\u044f \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u0443: 192.168.1.5;eth0;eth1[2] \u0437\u0432'\u044f\u0436\u0435 \u0432\u043a\u0430\u0437\u0430\u043d\u0456 IP - \u0432\u0441\u0456 IP \u0437 1-\u0433\u043e \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u0456 3-\u0442\u0454 IP 2-\u0433\u043e \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443.\n1-\u0439 IP \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u043c\u0435\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0432\u0441\u0456\u0445 \u043f\u043e\u0441\u043b\u0443\u0433, \u0432\u0441i \u0456\u043d\u0448\u0456 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u043c\u0443\u0442\u044c\u0441\u044f \u043b\u0438\u0448\u0435 \u0434\u043b\u044f \u0431\u0430\u043b\u0430\u043d\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.\n\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u0456 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456:\n%1
 ConfigView.label.mindownloads=\u041c\u0456\u043d\u0456\u043c\u0443\u043c \u043e\u0434\u043d\u043e\u0447\u0430\u0441\u043d\u0438\u0445 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c 
 UI.cannot_submit_blank_text=\u0412\u0438 \u043c\u0430\u0454\u0442\u0435 \u0432\u043a\u0430\u0437\u0430\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f.
-crypto.alert.as.warning=\u041c\u0435\u0440\u0435\u0436\u0456 '%1' \u0432\u0456\u0434\u043e\u043c\u043e, \u0449\u043e\u0431 \u0444\u0456\u043a\u0441\u0443\u0432\u0430\u0442\u0438 \u0444\u043e\u0440\u043c\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u0440\u0430\u0444\u0456\u043a\u0443, \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u0441\u043a\u043e\u0440\u043e\u0442\u0438\u0442\u0438 \u0435\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f. \u0428\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0431\u0443\u043b\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438\u043c - \u0456 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u0435/\u0437\u043c\u0456\u043d\u0435\u043d\u0435 \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0456\u0432 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u0457. 
+crypto.alert.as.warning=\u041c\u0435\u0440\u0435\u0436\u0456 '%1' \u0432\u0456\u0434\u043e\u043c\u043e, \u0449\u043e\u0431 \u0444\u0456\u043a\u0441\u0443\u0432\u0430\u0442\u0438 \u0444\u043e\u0440\u043c\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u0440\u0430\u0444\u0456\u043a\u0443, \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u0441\u043a\u043e\u0440\u043e\u0442\u0438\u0442\u0438 \u0435\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f. \u0428\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0431\u0443\u043b\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438\u043c - \u0456 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0435/\u0437\u043c\u0456\u043d\u0435\u043d\u0435 \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0456\u0432 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u0457. 
 ConfigView.section.interface.alerts=\u041f\u043e\u043f\u0435\u0440\u0435\u0434\u0436\u0435\u043d\u043d\u044f
-ConfigView.label.popupdownloadadded=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0432\u0438\u0440\u0438\u043d\u0430\u044e\u0447\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f, \u043a\u043e\u043b\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0434\u043e\u0434\u0430\u043d\u0435
+ConfigView.label.popupdownloadadded=\u0412\u0438\u0440\u0438\u043d\u0430\u044e\u0447\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f, \u043a\u043e\u043b\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0434\u043e\u0434\u0430\u043d\u0435
 popup.download.added="%1" \u0431\u0443\u0432 \u0434\u043e\u0434\u0430\u043d\u0438\u0439 \u0443 \u0442\u0432\u0456\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.
 MessageBoxWindow.nomoreprompting=\u041d\u0435 \u043d\u0430\u0433\u0430\u0434\u0443\u0432\u0430\u0442\u0438 \u043c\u0435\u043d\u0456 \u0437\u043d\u043e\u0432\u0443
 TorrentOptionsView.param.max.seeds=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437'\u0454\u0434\u043d\u0430\u043d\u044c \u0434\u043b\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
 TorrentOptionsView.param.alternative.value.enable=\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043f\u0456\u0434 \u0447\u0430\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 ConfigView.section.proxy.check.on.start=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u044f\u0442\u0438 \u0441\u0442\u0430\u0442\u0443\u0441 \u043f\u0440\u043e\u043a\u0441\u0456 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0443
 TransferStatsView.legend.pingaverage=\u0421\u0435\u0440\u0435\u0434\u043d\u0454
-TransferStatsView.legend.ping1=\u041c\u0456\u0441\u0446\u0435 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f 1
-TransferStatsView.legend.ping2=\u041c\u0456\u0441\u0446\u0435 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f 1
-TransferStatsView.legend.ping3=\u041c\u0456\u0441\u0446\u0435 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f 3
+TransferStatsView.legend.ping1=\u0420\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f 1
+TransferStatsView.legend.ping2=\u0420\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f 1
+TransferStatsView.legend.ping3=\u0420\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f 3
 ConfigView.section.interface.enabletray._mac=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0443 \u0432 \u0440\u044f\u0434\u043a\u0443 \u0441\u0442\u0430\u0442\u0443\u0441\u0443 [\u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443]
-ConfigView.label.closetotray._mac=\u041f\u0440\u0438 \u0437\u0430\u043a\u0440\u0438\u0442\u0442\u0456 \u0437\u0433\u043e\u0440\u043d\u0443\u0442\u0438 \u0432 \u0440\u044f\u0434\u043e\u043a \u0441\u0442\u0430\u0442\u0443\u0441\u0443
-ConfigView.label.minimizetotray._mac=\u0417\u0433\u043e\u0440\u043d\u0443\u0442\u0438 \u0432 \u0442\u0440\u0435\u0439
+ConfigView.label.closetotray._mac=\u041f\u0440\u0438 \u0437\u0430\u043a\u0440\u0438\u0442\u0442\u0456 \u0437\u0433\u043e\u0440\u043d\u0443\u0442\u0438 \u0432 \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0443 \u0440\u044f\u0434\u043a\u0430 \u0441\u0442\u0430\u0442\u0443\u0441\u0443
+ConfigView.label.minimizetotray._mac=\u0417\u0433\u043e\u0440\u0442\u0430\u0442\u0438 \u0432 \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0443 \u0440\u044f\u0434\u043a\u0430 \u0441\u0442\u0430\u0442\u0443\u0441\u0443
 OpenTorrentWindow.mb.existingFiles.title=\u0424\u0430\u0439\u043b(\u0438) \u0432\u0436\u0435 \u0456\u0441\u043d\u0443\u044e\u0442\u044c!
 OpenTorrentWindow.mb.existingFiles.text=\u0414\u0435\u044f\u043a\u0456 \u0437 \u0444\u0430\u0439\u043b\u0456\u0432 \u0432\u0436\u0435 \u0456\u0441\u043d\u0443\u044e\u0442\u044c \u0443 \u0442\u0435\u0446\u0456(\u043a\u0430\u0445) \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f :\n\n%1\n\u042f\u043a\u0449\u043e \u0412\u0438 \u043f\u0440\u043e\u0434\u043e\u0432\u0436\u0438\u0442\u0435, Vuze \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u0438 \u043d\u0430 \u0441\u043f\u0456\u0432\u043f\u0430\u0434\u0430\u043d\u043d\u044f \u0456 \u0437\u0430\u043c\u0456\u043d\u0438\u0442\u044c, \u044f\u043a\u0449\u043e \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e.
 splash.unloadingTorrents=\u041d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456  \u0442\u043e\u0440\u0435\u043d\u0442\u0438
@@ -2041,31 +2041,31 @@ ConfigView.section.file.defaultdir.autorename=\u0410\u0432\u0442\u043e\u043c\u04
 ConfigView.section.file.defaultdir.autorename.tooltip=\u0426\u0435 \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0454 \u0437\u0430\u043c\u0456\u043d\u0443 \u0442\u043e\u0440\u0435\u043d\u0442\u0430 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0456\u043d\u0448\u043e\u0433\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0430, \u044f\u043a\u0449\u043e \u0456\u043c\u0435\u043d\u0430 \u0444\u0430\u0439\u043b\u0456\u0432 \u043e\u0434\u043d\u0430\u043a\u043e\u0432\u0456
 alert.raised.at.close=(\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u0432\u0456\u0434 \u043f\u043e\u043f\u0435\u0440\u0435\u0434\u043d\u044c\u043e\u0433\u043e \u0437\u0430\u043a\u0440\u0438\u0442\u0442\u044f Vuze)
 Plugin.trackerpeerauth.name=\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0456\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0443
-Plugin.trackerpeerauth.info=\u0426\u0435 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u043f\u0440\u0430\u0446\u044e\u0454 \u0437 \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438, \u0434\u0435 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0438 \u0454 \u0434\u0456\u044e\u0447\u0438\u043c\u0438 \u0447\u043b\u0435\u043d\u0430\u043c\u0438
+Plugin.trackerpeerauth.info=\u0426\u0435 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u043f\u0440\u0430\u0446\u044e\u0454 \u0437 \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438, \u0434\u0435 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0438 \u0454 \u0447\u0438\u043d\u043d\u0438\u043c\u0438 \u0447\u043b\u0435\u043d\u0430\u043c\u0438
 Peers.column.maxupspeed=\u041c\u0430\u043a\u0441. \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442.
 Peers.column.maxdownspeed=\u041c\u0430\u043a\u0441. \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456
-MyTorrents.items.DownSpeedLimit.disabled=\u041d\u0435\u043c\u0430\u0454 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
+MyTorrents.items.DownSpeedLimit.disabled=\u041d\u0435\u043c\u0430 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 upnp.selectedaddresses=\u0410\u0434\u0440\u0435\u0441\u0438 (';' =\u0440\u043e\u0437\u0434\u0456\u043b\u0435\u043d\u0456, '-' =\u0432\u0456\u0434\u043c\u043e\u0432\u0430, '+' =\u0434\u043e\u0437\u0432\u0456\u043b) [\u043f\u043e\u0440\u043e\u0436\u043d\u0454: \u0431\u0443\u0434\u044c-\u044f\u043a\u0456]
-upnp.alert.multipledevice.warning=\u0417\u043d\u0430\u0439\u0434\u0435\u043d\u0456 \u0431\u0430\u0433\u0430\u0442\u043e\u0440\u0430\u0437\u043e\u0432\u0456 \u043f\u0440\u0438\u0441\u0442\u0440\u043e\u0457 UPnP  - \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u0438 \u043d\u0430 \u0432\u0438\u043c\u043e\u0433\u0443 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u043f\u043e\u0440\u0442\u0443 (\u0434\u0438\u0432\u0456\u0442\u044c\u0441\u044f \u043b\u043e\u0433\u0438 \u0456 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u044e UPnP)
+upnp.alert.multipledevice.warning=\u0417\u043d\u0430\u0439\u0434\u0435\u043d\u0456 \u0431\u0430\u0433\u0430\u0442\u043e\u0440\u0430\u0437\u043e\u0432\u0456 \u043f\u0440\u0438\u0441\u0442\u0440\u043e\u0457 UPnP  - \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0438\u0442\u0438 \u043d\u0430 \u0432\u0438\u043c\u043e\u0433\u0443 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u043f\u043e\u0440\u0442\u0443 (\u0434\u0438\u0432\u0456\u0442\u044c\u0441\u044f \u043b\u043e\u0433\u0438 \u0456 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f UPnP)
 UpdateMonitor.messagebox.restart.title=\u041f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0431\u0435\u0437\u043f\u0435\u0447\u0435\u043d\u043d\u044f
-UpdateMonitor.messagebox.restart.text=Vuze \u0442\u0456\u043b\u044c\u043a\u0438 \u0449\u043e \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u0432 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0432\u0430\u0436\u043b\u0438\u0432\u043e\u0433\u043e \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f, \u044f\u043a\u0435 \u0434\u043b\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438.
-PiecesView.BlockView.Have=\u041c\u0430\u0442\u0438
-PiecesView.BlockView.NoHave=\u041d\u0435 \u043c\u0430\u0442\u0438
+UpdateMonitor.messagebox.restart.text=Vuze \u043b\u0438\u0448\u0435 \u0449\u043e \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u0432 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0432\u0430\u0436\u043b\u0438\u0432\u043e\u0433\u043e \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f, \u044f\u043a\u0435 \u0434\u043b\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438.
+PiecesView.BlockView.Have=\u041d\u0430\u044f\u0432\u043d\u043e
+PiecesView.BlockView.NoHave=\u041d\u0435 \u043d\u0430\u044f\u0432\u043d\u043e
 PiecesView.BlockView.Header=%1 \u0441\u0442\u043e\u0432\u043f\u0435\u0446\u044c(\u0446\u0456\u0432), %2 \u0440\u044f\u0434\u043e\u043a(\u043a\u0456\u0432), %3 \u0447\u0430\u0441\u0442\u0438\u043d
 ConfigView.section.update.autodownload=\u041f\u0456\u0441\u043b\u044f \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
 Peers.column.peer_id=ID \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
 Peers.column.peer_id.info=ID \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 \u0432 \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u0456\u0439 \u0444\u043e\u0440\u043c\u0456 
 Peers.column.peer_byte_id=ID \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
 Peers.column.peer_byte_id.info=ID \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 \u0432 \u0431\u0430\u0439\u0442\u043e\u0432\u0456\u0439 \u0444\u043e\u0440\u043c\u0456
-Peers.column.handshake_reserved=\u0417\u0430\u0445\u043e\u043f\u043b\u0435\u043d\u043d\u044f \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u043e\u0432\u0430\u043d\u0438\u0445 \u0431\u0430\u0439\u0442\u0456\u0432
-Peers.column.handshake_reserved.info=\u0412\u0440\u0430\u0445\u043e\u0432\u0443\u0454, \u0449\u043e \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u043e\u0432\u0430\u043d\u0456 \u0431\u0456\u0442\u0438 \u0437\u0430\u0445\u043e\u043f\u043b\u0435\u043d\u0456 BT
+Peers.column.handshake_reserved=\u0417\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u043e\u0432\u0430\u043d\u0456 \u0431\u0430\u0439\u0442\u0438 \u0434\u043b\u044f \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f
+Peers.column.handshake_reserved.info=\u041f\u043e\u043a\u0430\u0437\u0443\u0454, \u0441\u043a\u0456\u043b\u044c\u043a\u0438 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u043e\u0432\u0430\u043d\u043e \u0431\u0456\u0442\u0456\u0432 \u0434\u043b\u044f \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f BT
 Peers.column.client_identification=\u041e\u0442\u043e\u0442\u043e\u0436\u043d\u0435\u043d\u043d\u044f \u043a\u043b\u0456\u0454\u043d\u0442\u0430
-Peers.column.client_identification.info=\u041e\u0442\u043e\u0442\u043e\u0436\u043d\u044e\u0454 \u0456\u043c'\u044f \u043a\u043b\u0456\u0454\u043d\u0442\u0430 \u0437  Vuze - \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0436\u0435\u043d\u043d\u044f
+Peers.column.client_identification.info=\u041f\u043e\u043a\u0430\u0437\u0443\u0454 \u043d\u0435\u043e\u043f\u0440\u0430\u0446\u044c\u043e\u0432\u0430\u043d\u0435 \u0456\u043c'\u044f \u043a\u043b\u0456\u0454\u043d\u0442\u0430 Vuze - \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0436\u0435\u043d\u043d\u044f
 dht.warn.user=\u041f\u043e\u043f\u0435\u0440\u0435\u0434\u0436\u0435\u043d\u043d\u044f \u043f\u0440\u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0456\u0439\u043d\u0456 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438 NAT \u0430\u0431\u043e \u043f\u043e\u0440\u0442\u0443
-ConfigView.label.openbar.incomplete=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0442\u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
+ConfigView.label.openbar.incomplete=\u041f\u0430\u043d\u0435\u043b\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c: \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 ConfigView.label.openbar.complete=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0442\u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u0441\u0456\u0434\u0435\u0440\u0456\u0432
 ConfigView.label.transferbar.remember_location=\u041f\u0430\u043c'\u044f\u0442\u0430\u0442\u0438 \u043e\u0441\u0442\u0430\u043d\u043d\u0454 \u0440\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0430\u043d\u0435\u043b\u0456 \u043f\u0435\u0440\u0435\u0434\u0430\u0447
-ConfigView.section.transfer.autospeed.forcemin=\u041f\u0440\u0438\u0448\u0432\u0438\u0434\u0448\u0435\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043f\u0440\u0438 \u0437\u0432'\u044f\u0437\u043a\u0443, %1 
+ConfigView.section.transfer.autospeed.forcemin=\u041f\u0440\u0438\u0448\u0432\u0438\u0434\u0448\u0435\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043f\u0440\u0438 \u0432\u0438\u0440\u0456\u0432\u043d\u044e\u0432\u0430\u043d\u043d\u0456 \u0437\u0432'\u044f\u0437\u043a\u0443, %1 
 MainWindow.menu.tools.speedtest=\u0412\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456...
 speedtest.wizard.title=\u0412\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456
 speedtest.wizard.run=\u0412\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456
@@ -2095,7 +2095,7 @@ SpeedTestWizard.finish.panel.max.seeding.upload=\u041c\u0430\u043a\u0441\u0438\u
 SpeedTestWizard.finish.panel.max.download=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c
 SpeedTestWizard.finish.panel.enabled=\u0443\u0432\u0456\u043c\u043a.
 SpeedTestWizard.finish.panel.disabled=\u0432\u0438\u043c\u043a.
-SpeedTestWizard.abort.message.scheduled.in=\u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u043f\u043b\u0430\u043d\u0443\u0454\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 ... %1 \u0441\u0435\u043a\u0443\u043d\u0434(\u0438)"
+SpeedTestWizard.abort.message.scheduled.in=\u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u043f\u043b\u0430\u043d\u0443\u0454\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437... %1 \u0441\u0435\u043a\u0443\u043d\u0434(\u0438)"
 SpeedTestWizard.abort.message.unsupported.type=\u0422\u0438\u043f \u0432\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0435 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454\u0442\u044c\u0441\u044f!!!!
 SpeedTestWizard.abort.message.manual.abort=\u0412\u0440\u0443\u0447\u043d\u0443 \u043f\u0440\u0438\u043f\u0438\u043d\u0435\u043d\u0438\u0439
 SpeedTestWizard.abort.message.scheduling.failed=\u041f\u043b\u0430\u043d\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0435\u0432\u0434\u0430\u043b\u0435
@@ -2115,7 +2115,7 @@ window.uiswitcher.title=\u0412\u0438\u0431\u0456\u0440 \u0456\u043d\u0442\u0435\
 window.uiswitcher.text=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0442\u043e\u0439 \u0432\u0438\u0433\u043b\u044f\u0434 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438, \u044f\u043a\u0438\u0439 \u0437\u0430\u0434\u043e\u0432\u0456\u043b\u044c\u043d\u044f\u0442\u0438\u043c\u0435 \u0432\u0430\u0448\u0456 \u043f\u043e\u0442\u0440\u0435\u0431\u0438.
 window.uiswitcher.NewUI.text=* \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u0447\u0430\u0442\u043a\u0456\u0432\u0446\u0456\u0432 \u0456 \u043d\u043e\u0432\u0438\u0445 \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0456\u0432.\n\n* \u041b\u0435\u0433\u043a\u0435, \u0456\u043d\u0442\u0443\u0457\u0442\u0438\u0432\u043d\u0435 \u0433\u0440\u0430\u0444\u0456\u0447\u043d\u0435 \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u043d\u044f\n\n* \u041e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u0432\u0438\u0433\u043b\u044f\u0434 \u0434\u043b\u044f \u043f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0456 Vuze 
 window.uiswitcher.ClassicUI.title=\u041a\u043b\u0430\u0441\u0438\u0447\u043d\u0438\u0439 \u0432\u0438\u0433\u043b\u044f\u0434
-window.uiswitcher.ClassicUI.text=* \u0417\u0431\u0435\u0440\u0456\u0433\u0430\u0454 \u0444\u0443\u043d\u043a\u0446\u0456\u043e\u043d\u0430\u043b\u044c\u043d\u0456\u0441\u0442\u044c \u043a\u043b\u0456\u0454\u043d\u0442\u0430 \u0441\u0435\u0440\u0456\u0439 2.x \n* Vuze -\u0448\u0430\u043f\u043a\u0430 \u043d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438\u043c\u0435\u0442\u044c\u0441\u044f
+window.uiswitcher.ClassicUI.text=* \u0417\u0431\u0435\u0440\u0456\u0433\u0430\u0454 \u0444\u0443\u043d\u043a\u0446\u0456\u043e\u043d\u0430\u043b\u044c\u043d\u0456\u0441\u0442\u044c \u043a\u043b\u0456\u0454\u043d\u0442\u0430 \u0432\u0435\u0440\u0441\u0456\u0439 2.x \n* \u0428\u0430\u043f\u043a\u0430 Vuze \u043d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438\u043c\u0435\u0442\u044c\u0441\u044f
 window.uiswitcher.bottom.text=\u0412\u0430\u0448 \u0432\u0438\u0431\u0456\u0440 \u043c\u043e\u0436\u0435 \u043b\u0435\u0433\u043a\u043e \u0431\u0443\u0442\u0438 \u0437\u043c\u0456\u043d\u0435\u043d\u0438\u043c \u0437\u043d\u043e\u0432\u0443 \u043d\u0430\u0442\u0438\u0441\u043a\u043e\u043c \u043a\u043d\u043e\u043f\u043a\u0438 UI , \u0456 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u044e \u0437\u043c\u0456\u043d\u043e\u044e \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443
 iconBar.switch.tooltip=\u041f\u0435\u0440\u0435\u043c\u0438\u043a\u0430\u0447 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 Vuze
 VivaldiView.notAvailable=\u041d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439 \u0432\u0438\u0433\u043b\u044f\u0434 Vivaldi
@@ -2125,14 +2125,15 @@ restart.error.fnf='%1' \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u
 restart.error.pnf=\u0428\u043b\u044f\u0445 '%1' \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u0438\u0439
 restart.error.bad=\u041f\u043e\u0433\u0430\u043d\u0438\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u0444\u0430\u0439\u043b\u0443 \u0434\u043b\u044f '%1'
 restart.error.denied=\u0414\u043e\u0441\u0442\u0443\u043f \u043a\u0435\u0440\u0443\u0432\u0430\u043d\u043d\u044f '%1' \u043d\u0435 \u043d\u0430\u0434\u0430\u043d\u0438\u0439.  \u041f\u0435\u0440\u0435\u043a\u043e\u043d\u0430\u0439\u0442\u0435\u0441\u044f, \u0449\u043e \u0432\u0438 \u043c\u0430\u0454\u0442\u0435 \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0456 \u043f\u0440\u0430\u0432\u0430, \u0449\u043e\u0431 \u043a\u0435\u0440\u0443\u0432\u0430\u0442\u0438 \u0446\u0456\u0454\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043e\u044e.
-TableColumn.header.date_completed=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0439
+TableColumn.header.date_completed=\u0417\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0438\u0439
 TableColumn.menu.date_added.reset=\u0421\u0442\u0435\u0440\u0442\u0438 \u0434\u0430\u0442\u0443
-ConfigView.section.ipfilter.discardbanning=\u0411\u043b\u043e\u043a\u0443\u0432\u0430\u0442\u0438 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432, \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f \u0434\u0430\u043d\u0438\u0445 \u0434\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u0434\u0430\u043d\u0438\u0445 \u044f\u043a\u0438\u0445 \u043c\u0435\u043d\u0448\u0435\n[0: \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0438]
+ConfigView.section.ipfilter.discardbanning=\u0411\u043b\u043e\u043a\u0443\u0432\u0430\u0442\u0438 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432, \u0432 \u044f\u043a\u0438\u0445 \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f \u0432\u0456\u0434\u0445\u0438\u043b\u0435\u043d\u0438\u0445 \u0434\u0430\u043d\u0438\u0445 \u0434\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u0434\u0430\u043d\u0438\u0445 \u043c\u0435\u043d\u0448\u0435\n[0: \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0438]
 ConfigView.section.ipfilter.discardminkb=\u041c\u0456\u043d\u0456\u043c\u0443\u043c %1 \u0437\u0431\u043e\u0457\u0432 \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u0441\u0442\u043e\u0441\u0443\u0432\u0430\u043d\u043d\u044f\u043c \u0441\u043f\u0456\u0432\u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f
 ConfigView.interface.start.advanced=\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u0438 \u0432 \u0440\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u043e\u043c\u0443 \u0432\u0438\u0433\u043b\u044f\u0434\u0456(AZ 2.x)
 MyTorrents.column.ColumnQuality=\u042f\u043a\u0456\u0441\u0442\u044c
 MyTorrents.column.ColumnSpeed=\u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c
-MyTorrents.column.ColumnProgressETA.StreamReady=\u041f\u043e\u0442\u0456\u043a \u0433\u043e\u0442\u043e\u0432\u0438\u0439
+MyTorrents.column.ColumnProgressETA.2ndLine=\u0417\u0430\u043b\u0438\u0448\u0438\u043b\u043e\u0441\u044f: %1
+MyTorrents.column.ColumnProgressETA.StreamReady=\u0413\u043e\u0442\u043e\u0432\u0438\u0439 \u0434\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0457 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0456
 MyTorrents.column.ColumnProgressETA.PlayableIn=\u0412\u0456\u0434\u0442\u0432\u043e\u0440\u044e\u0432\u0430\u043d\u0438\u0439 \u0432  %1
 TableColumn.header.Quality=\u042f\u043a\u0456\u0441\u0442\u044c
 TableColumn.header.Speed=\u0428\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c
@@ -2156,7 +2157,7 @@ v3.MainWindow.tab.advanced=\u0414\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u043
 v3.MainWindow.menu.home=&\u041f\u0430\u043d\u0435\u043b\u044c \u0456\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0456\u0432
 v3.MainWindow.menu.browse=&\u041d\u0430 Vuze
 v3.MainWindow.menu.library=&\u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0430
-v3.MainWindow.menu.publish=\u041f\u0443\u0431\u043b\u0456&\u043a\u0443\u0432\u0430\u0442\u0438
+v3.MainWindow.menu.publish=&\u041f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u0442\u0438
 v3.MainWindow.menu.advanced=&\u0414\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u043e
 v3.MainWindow.menu.view.searchbar=\u041f\u0430\u043d\u0435\u043b\u044c \u043f\u043e\u0448\u0443\u043a\u0443
 v3.MainWindow.menu.view.tabbar=\u0420\u044f\u0434\u043e\u043a \u043f\u0430\u043d\u0435\u043b\u0456
@@ -2178,13 +2179,10 @@ v3.MainWindow.xofx=%1 \u0437 %2
 v3.MainWindow.Loading=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.. \u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0437\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435
 v3.filter-bar=\u0424\u0456\u043b\u044c\u0442\u0440 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430:
 v3.MainWindow.search.defaultText=Vuze , \u0448\u0443\u043a\u0430\u0439!
-v3.mb.delPublished.title=\u041f\u0440\u0438\u043f\u0438\u043d\u0438\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u0438 \u0432\u043c\u0456\u0441\u0442
-v3.mb.delPublished.text=\u0423\u0412\u0410\u0413\u0410: \u0426\u044f \u0434\u0456\u044f \u043d\u0435 \u0437\u043d\u0438\u0449\u0438\u0442\u044c \u0432\u0430\u0448 \u043e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u0438\u0439 \u0432\u043c\u0456\u0441\u0442 '%1' \u0437 <A HREF="%2">%3</A> .\n\n\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c "\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438" \u043b\u0438\u0448\u0435 \u0432 \u0442\u043e\u043c\u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443, \u044f\u043a\u0449\u043e \u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435, \u0449\u043e\u0431 \u0432\u0430\u0448 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0437\u0430\u043b\u0438\u0448\u0438\u0432\u0441\u044f \u043e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u0438\u043c \u0456 \u0439\u043e\u0433\u043e \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438, \u0430\u043b\u0435 \u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0432\u0456\u043b\u044c\u043d\u0438\u0442\u0438 \u0432\u0430\u0448\u0443 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u0443 \u0441\u043f\u0440\u043e\u043c\u043e\u0436\u043d\u0456\u0441\u0442\u044c. \u041f\u0435\u0440\u0435\u043a\u043e\u043d\u0430\u0439\u0442\u0435\u0441\u044f, \u0449\u043e \u043f\u0440\u043e\u0446\u0435\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u0432\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0442\u0438\u043c, \u044f\u043a \u0412\u0438 \u0437\u0440\u043e\u0431\u0438\u0442\u0435 \u0442\u0430\u043a (<A HREF="%4">\u042f\u043a</A>?).\n\n\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c "\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438", \u044f\u043a\u0449\u043e \u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0446\u0456\u043b\u043a\u043e\u043c \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0432\u0430\u0448 \u043e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 %3, \u0456 \u043d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 (X) \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 \u043f\u0443\u0431\u043b\u0456\u043a\u0430\u0446\u0456\u0457.\n\n<A HREF="%4">\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u0438 \u0431\u0456\u043b\u044c\u0448\u0435</A>.\n\n
+v3.mb.delPublished.title=\u041f\u0440\u0438\u043f\u0438\u043d\u0438\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e
+v3.mb.delPublished.text=\u0423\u0412\u0410\u0413\u0410: \u0426\u044f \u0434\u0456\u044f \u043d\u0435 \u0437\u043d\u0438\u0449\u0438\u0442\u044c \u0432\u0430\u0448\u0443 \u043e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u0443 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e '%1' \u0437 <A HREF="%2">%3</A> .\n\n\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c "\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438" \u043b\u0438\u0448\u0435 \u0432 \u0442\u043e\u043c\u0443 \u0432\u0438\u043f\u0430\u0434\u043a\u0443, \u044f\u043a\u0449\u043e \u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435, \u0449\u043e\u0431 \u0432\u0430\u0448\u0430 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u0437\u0430\u043b\u0438\u0448\u0430\u043b\u0430\u0441\u044f \u043e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u043d\u043e\u044e \u0456 \u0457\u0457 \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438, \u0430\u043b\u0435 \u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0432\u0456\u043b\u044c\u043d\u0438\u0442\u0438 \u0432\u0430\u0448\u0443 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u0443 \u0441\u043f\u0440\u043e\u043c\u043e\u0436\u043d\u0456\u0441\u0442\u044c. \u041f\u0435\u0440\u0435\u043a\u043e\u043d\u0430\u0439\u0442\u0435\u0441\u044f, \u0449\u043e \u043f\u0440\u043e\u0446\u0435\u0441 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u0432\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0442\u0438\u043c, \u044f\u043a \u0412\u0438 \u0437\u0440\u043e\u0431\u0438\u0442\u0435 \u0442\u0430\u043a (<A HREF="%4">\u042f\u043a</A>?).\n\n\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c "\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438", \u044f\u043a\u0449\u043e \u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0446\u0456\u043b\u043a\u043e\u043c \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0432\u0430\u0448\u0443 \u043e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u0443 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e %3, \u0456 \u043d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 (X) \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 \u043f\u0443\u0431\u043b\u0456\u043a\u0430\u0446\u0456\u0457.\n\n<A HREF="%4">\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u0438 \u0431\u0456\u043b\u044c\u0448\u0435</A>.\n\n
 v3.mb.delPublished.delete=&\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438
 v3.mb.delPublished.cancel=&\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438
-v3.HomeReminder.title=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0434\u043e\u0434\u0430\u043d\u0435
-v3.HomeReminder.text='%1' \u0431\u0443\u0432 \u0434\u043e\u0434\u0430\u043d\u0438\u0439 \u0434\u043e \u0432\u0430\u0448\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0443 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c.\n\n\u042f\u043a\u0449\u043e \u0432\u0438 \u0431\u0430\u0436\u0430\u0454\u0442\u0435 \u0441\u043f\u043e\u0441\u0442\u0435\u0440\u0456\u0433\u0430\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0435\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f, \u0430\u0431\u043e \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0444\u0430\u0439\u043b \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044f, \u043a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043f\u043e \u0442\u0430\u0431\u043b\u0438\u0446\u0456 \u041f\u0430\u043d\u0435\u043b\u0456 \u0456\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0456\u0432.
-v3.HomeReminder.gohome=\u041f\u0435\u0440\u0435\u043c\u043a\u043d\u0443\u0442\u0438\u0441\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u044e \u043f\u0430\u043d\u0435\u043b\u0456 \u0456\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0456\u0432
 v3.mb.openFile.title=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0444\u0430\u0439\u043b
 v3.mb.openFile.text.known=\u0426\u0435\u0439 \u0432\u043c\u0456\u0441\u0442 \u043d\u0435 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u0432\u0430\u0447\u0435\u043c Vuze Player. \u0417\u0432\u0456\u0440\u0442\u0435\u0441\u044f \u0437 \u0441\u0442\u0432\u043e\u0440\u0435\u043d\u043e\u044e \u043d\u0430\u0448\u0438\u043c \u0441\u0443\u0441\u043f\u0456\u043b\u044c\u0441\u0442\u0432\u043e\u043c <a href="http://www.azureuswiki.com/index.php/Playback_Guide">\u0414\u043e\u0432\u0456\u0434\u043a\u043e\u044e \u043f\u043e \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044e</a>.\n\n\u0422\u0438\u043f \u0444\u0430\u0439\u043b\u0443: %2 (%3)\n
 v3.mb.openFile.text.unknown=\u0426\u0435\u0439 \u0432\u043c\u0456\u0441\u0442 \u043d\u0435 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u0432\u0430\u0447\u0435\u043c Vuze Player. \u0417\u0432\u0456\u0440\u0442\u0435\u0441\u044f \u0437 \u0441\u0442\u0432\u043e\u0440\u0435\u043d\u043e\u044e \u043d\u0430\u0448\u0438\u043c \u0441\u0443\u0441\u043f\u0456\u043b\u044c\u0441\u0442\u0432\u043e\u043c <a href="http://www.azureuswiki.com/index.php/Playback_Guide">\u0414\u043e\u0432\u0456\u0434\u043a\u043e\u044e \u043f\u043e \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044e</a> for help.\n\n\u0420\u043e\u0448\u0438\u0440\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443 : %2\n
@@ -2197,8 +2195,8 @@ v3.mb.PlayFileNotFound.text=\u0424\u0430\u0439\u043b\u0438 \u0434\u043b\u044f '%
 v3.mb.PlayFileNotFound.button.remove=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0437 Vuze
 v3.mb.PlayFileNotFound.button.redownload=\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456 \u0434\u0430\u043d\u0456
 v3.mb.PlayFileNotFound.button.find=\u041f\u043e\u0448\u0443\u043a \u0432\u0440\u0443\u0447\u043d\u0443..
-v3.mb.deletePurchased.title=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u043a\u0443\u043f\u043b\u0435\u043d\u0438\u0439 \u0432\u043c\u0456\u0441\u0442
-v3.mb.deletePurchased.text=\u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0432\u043c\u0456\u0441\u0442 '%1'?\n\n\u0426\u0435\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u043e\u043a\u0443\u043f\u043a\u0438 \u0430\u0431\u043e \u0432\u043a\u0430\u0437\u0430\u043d\u043d\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043b\u043e\u0433\u0456\u043d\u0443.
+v3.mb.deletePurchased.title=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u043a\u0443\u043f\u043b\u0435\u043d\u0443 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e
+v3.mb.deletePurchased.text=\u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 '%1'?\n\n\u0426\u044f \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u043e\u043a\u0443\u043f\u043a\u0438 \u0430\u0431\u043e \u0432\u043a\u0430\u0437\u0430\u043d\u043d\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043b\u043e\u0433\u0456\u043d\u0443.
 v3.mb.deletePurchased.button.delete=&\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438
 v3.mb.deletePurchased.button.cancel=&\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438
 v3.topbar.menu.show.logo=\u0424\u0456\u0440\u043c\u043e\u0432\u0438\u0439 \u0437\u043d\u0430\u043a
@@ -2206,13 +2204,13 @@ v3.topbar.menu.show.plugin=\u0414\u0456\u043b\u044f\u043d\u043a\u0430 \u0434\u04
 v3.topbar.menu.show.search=\u041f\u043e\u0448\u0443\u043a
 splash.initializeCore=\u0406\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u044f \u044f\u0434\u0440\u0430
 splash.initializeUIElements=\u0406\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u044f \u0435\u043b\u0435\u043c\u0435\u043d\u0442\u0456\u0432 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443
-ConfigView.section.transfer.autospeedbeta=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c - \u0431\u0435\u0442\u0430
+ConfigView.section.transfer.autospeedbeta=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c (beta)
 #
 ConfigView.section.ipfilter.peerblocking.group=\u0411\u043b\u043e\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
 ConfigView.section.ipfilter.autoload.group=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 ConfigView.section.ipfilter.autoload.file=\u0424\u0430\u0439\u043b \u0444\u0456\u043b\u044c\u0442\u0440\u0443 IP \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
-ConfigView.section.ipfilter.autoload.info=\u041f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454 \u0444\u043e\u0440\u043c\u0430\u0442\u0438 DAT (eMule), P2P (PeerGuardian, splist), and P2B v1,2,3 (PeerGuardian 2).  \u0424\u0430\u0439\u043b \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u043c\u0456\u0441\u0446\u0435\u0432\u0438\u043c \u0430\u0431\u043e URL, zip'\u043e\u043c, gzip'\u043e\u043c \u0430\u0431\u043e \u0442\u0435\u043a\u0441\u0442\u043e\u043c.  URL-\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 7 \u0434\u043d\u0456\u0432, \u0442\u043e\u0434\u0456 \u044f\u043a \u0444\u0430\u0439\u043b\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438\u043c\u0443\u0442\u044c\u0441\u044f \u0432 \u043c\u0435\u0436\u0430\u0445 \u0445\u0432\u0438\u043b\u0438\u043d\u0438.
-ConfigView.section.ipfilter.autoload.loadnow=\u0422\u0440\u0438\u0432\u0430\u0454 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
+ConfigView.section.ipfilter.autoload.info=\u041f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454 \u0444\u043e\u0440\u043c\u0430\u0442\u0438 DAT (eMule), P2P (PeerGuardian, splist), and P2B v1,2,3 (PeerGuardian 2).  \u0424\u0430\u0439\u043b \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u043c\u0456\u0441\u0446\u0435\u0432\u0438\u043c \u0430\u0431\u043e \u0430\u0434\u0440\u0435\u0441\u043e\u044e, zip'\u043e\u043c, gzip'\u043e\u043c \u0430\u0431\u043e \u0442\u0435\u043a\u0441\u0442\u043e\u043c.  \u0430\u0434\u0440\u0435\u0441\u0430-\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 7 \u0434\u043d\u0456\u0432, \u0442\u043e\u0434\u0456 \u044f\u043a \u0444\u0430\u0439\u043b\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438\u043c\u0443\u0442\u044c\u0441\u044f \u0432 \u043c\u0435\u0436\u0430\u0445 \u0445\u0432\u0438\u043b\u0438\u043d\u0438.
+ConfigView.section.ipfilter.autoload.loadnow=\u0417\u0430\u0432\u0430\u0442\u043d\u0430\u0436\u0438\u0442\u0438 \u0437\u0430\u0440\u0430\u0437
 splash.loadIpFilters=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0444\u0456\u043b\u044c\u0442\u0440\u0456\u0432 IP...
 SpeedTestWizard.set.upload.title=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043c\u0435\u0436\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456:
 SpeedTestWizard.set.download.label=\u041e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f:
@@ -2228,7 +2226,7 @@ mb.azmustclose.title=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u0437\u0430\u04
 mb.azmustclose.text=Vuze \u043f\u043e\u0432\u0438\u043d\u0435\u043d \u0437\u0430\u043a\u0440\u0438\u0442\u0438\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 (\u043f\u0435\u0440\u0435)\u0437\u0430\u043f\u0443\u0441\u043a\u0443 Vuze \u0432\u0456\u0434 \u0456\u043c\u0435\u043d\u0456 \u0410\u0434\u043c\u0456\u043d\u0456\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430.\n\n\u041f\u0456\u0441\u043b\u044f \u0437\u0430\u043a\u0440\u0438\u0442\u0442\u044f Vuze \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0456\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0443 \u0432\u0440\u0443\u0447\u043d\u0443.
 network.ipv6.prefer.addresses=\u0412\u0456\u0434\u0434\u0430\u0432\u0430\u0442\u0438 \u043f\u0435\u0440\u0435\u0432\u0430\u0433\u0443 \u0430\u0434\u0440\u0435\u0441\u0430\u043c IPv6, \u043a\u043e\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u044f\u043a IPv6, \u0442\u0430\u043a \u0456 IPv4 
 network.bindError=\u0417\u0430\u043a\u0440\u0456\u043f\u043b\u0435\u043d\u043d\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e \u0433\u043d\u0456\u0437\u0434\u0430 \u043d\u0435\u0432\u0434\u0430\u043b\u0435, \u0430\u0434\u0440\u0435\u0441, \u044f\u043a\u0456 \u0431 \u043f\u0456\u0434\u0445\u043e\u0434\u0438\u043b\u0438, \u043d\u0435 \u0437\u043d\u0430\u0439\u0448\u043b\u043e\u0441\u044f, \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u0441\u0432\u043e\u0457 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 \u0437\u0430\u043a\u0440\u0456\u043f\u043b\u0435\u043d\u043d\u044f \u0437\u0430 IP.
-network.enforce.ipbinding=\u041f\u0440\u0438\u0448\u0432\u0438\u0434\u0448\u0443\u0432\u0430\u0442\u0438 \u0432\u043a\u0430\u0437\u0430\u043d\u0456 IP \u043d\u0430\u0432\u0456\u0442\u044c, \u043a\u043e\u043b\u0438 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0438 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456; \u0437\u0430\u043f\u043e\u0431\u0456\u0433\u0430\u0442\u0438 \u0431\u0443\u0434\u044c-\u044f\u043a\u0438\u043c \u0437\u0432'\u044f\u0437\u043a\u0430\u043c, \u044f\u043a\u0449\u043e \u0436\u043e\u0434\u0435\u043d \u0437 \u0432\u043a\u0430\u0437\u0430\u043d\u0438\u0445 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0456\u0432 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439
+network.enforce.ipbinding=\u041f\u0440\u0438\u0448\u0432\u0438\u0434\u0448\u0443\u0432\u0430\u0442\u0438 \u0432\u043a\u0430\u0437\u0430\u043d\u0456 IP \u043d\u0430\u0432\u0456\u0442\u044c, \u043a\u043e\u043b\u0438 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0438 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456; \u0437\u0430\u043f\u043e\u0431\u0456\u0433\u0430\u0454 \u0431\u0443\u0434\u044c-\u044f\u043a\u0438\u043c \u0437\u0432'\u044f\u0437\u043a\u0430\u043c, \u044f\u043a\u0449\u043e \u0436\u043e\u0434\u0435\u043d \u0437 \u0432\u043a\u0430\u0437\u0430\u043d\u0438\u0445 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0456\u0432 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439
 DHTView.title.full_v6=\u0420\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0435\u043d\u0430 \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u0438\u0445 IPv6
 ConfigView.pluginlist.loadSelected=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0432\u0438\u0431\u0440\u0430\u043d\u0456
 SpeedView.stats.asn=\u041c\u0435\u0440\u0435\u0436\u0430:
@@ -2241,7 +2239,7 @@ SpeedView.stats.measuredmin=\u041c\u0456\u043d\u0456\u043c\u0430\u043b\u044c\u04
 SpeedView.stats.manual=\u0432\u0438\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430
 ConfigView.section.transfer.autospeed.networks=\u041c\u0435\u0440\u0435\u0436\u0435\u0432\u0456 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456
 ConfigView.section.transfer.autospeed.resetnetwork=\u0421\u043a\u0438\u043d\u0443\u0442\u0438 \u043c\u0435\u0440\u0435\u0436\u0435\u0432\u0456 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456
-ConfigView.section.transfer.autospeed.network.info=\u041c\u0435\u0436\u0456 \u0437\u0430\u0437\u0432\u0438\u0447\u0430\u0439 \u043e\u0431\u0447\u0438\u0441\u043b\u044e\u044e\u0442\u044c\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0440\u043e\u0442\u044f\u0433\u043e\u043c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0430\u0431\u043e \u0454 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456. \u042f\u043a\u0449\u043e \u0432\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0440\u0443\u0447\u043d\u0443 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0438\u0437\u0443\u0432\u0430\u0442\u0438 \u0457\u0445, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0439\u0442\u0435 \u043d\u0438\u0436\u0447\u0435 \u043d\u0430\u0432\u0435\u0434\u0435\u043d\u0443 \u043e\u043f\u0446\u0456\u044e.\n\u0412\u0441\u0456 \u043c\u0435\u0436\u0456, \u043e\u043a\u0440\u0456\u043c '\u0432\u0438\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e\u0457', \u0437\u0433\u043e\u0434\u043e\u043c \u0431\u0443\u0434\u0443\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0441\u043a\u043e\u0440\u0435\u043a\u0442\u043e\u0432\u0430\u043d\u0456, \u044f\u043a\u0449\u043e \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e. \n\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f, \u0430 \u043f\u043e\u0442\u0456\u043c \u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0439\u043e\u0433\u043e \u0442\u0438\u043f. \u0417\u0430\u0443\u0432\u0430\u0436\u0442\u0435, \u0449\u043e \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u043d\u0430\u0445\u043e\u0434\u044f\u0442\u044c\u0441\u044f \u0432 %1.
+ConfigView.section.transfer.autospeed.network.info=\u041c\u0435\u0436\u0456 \u0437\u0432\u0438\u0447\u0430\u0439\u043d\u043e \u043e\u0431\u0447\u0438\u0441\u043b\u044e\u044e\u0442\u044c\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0440\u043e\u0442\u044f\u0433\u043e\u043c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0430\u0431\u043e \u0454 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456. \u042f\u043a\u0449\u043e \u0432\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0440\u0443\u0447\u043d\u0443 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0438\u0437\u0443\u0432\u0430\u0442\u0438 \u0457\u0445, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0439\u0442\u0435 \u043d\u0438\u0436\u0447\u0435 \u043d\u0430\u0432\u0435\u0434\u0435\u043d\u0443 \u043e\u043f\u0446\u0456\u044e.\n\u0412\u0441\u0456 \u043c\u0435\u0436\u0456, \u043e\u043a\u0440\u0456\u043c '\u0432\u0438\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e\u0457', \u0437\u0433\u043e\u0434\u043e\u043c \u0431\u0443\u0434\u0443\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0441\u043a\u043e\u0440\u0435\u043a\u0442\u043e\u0432\u0430\u043d\u0456, \u044f\u043a\u0449\u043e \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e. \n\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f, \u0430 \u043f\u043e\u0442\u0456\u043c \u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0439\u043e\u0433\u043e \u0442\u0438\u043f. \u0417\u0430\u0443\u0432\u0430\u0436\u0442\u0435, \u0449\u043e \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u043d\u0430\u0445\u043e\u0434\u044f\u0442\u044c\u0441\u044f \u0432 %1.
 dialog.uiswitcher.restart.title=\u041f\u0435\u0440\u0435\u043c\u0438\u043a\u0430\u0447 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443: \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a Vuze
 dialog.uiswitcher.restart.text=Vuze \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443, \u0449\u043e\u0431 \u043f\u0435\u0440\u0435\u043c\u043a\u043d\u0443\u0442\u0438\u0441\u044f \u0432 \u043d\u043e\u0432\u0438\u0439 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.
 TrayWindow.menu.close=\u0417\u0430\u043a\u0440\u0438\u0442\u0438 \u043a\u043e\u0448\u0438\u043a \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c
@@ -2255,9 +2253,9 @@ PeerSocket.unknown_shadow_style=\u041d\u0435\u0432\u0456\u0434\u043e\u043c\u0438
 OpenTorrentWindow.mb.askCreateDir.title=\u0422\u0435\u043a\u0430 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043d\u0435 \u0456\u0441\u043d\u0443\u0454.
 OpenTorrentWindow.mb.askCreateDir.text=\u0422\u0435\u043a\u0430 \u043f\u0440\u0438\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f '%1' \u043d\u0435 \u0456\u0441\u043d\u0443\u0454.\n\n\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0457\u0457 \u0437\u0430\u0440\u0430\u0437? 
 SpeedView.stats.estimatechoke=\u041e\u0446\u0456\u043d\u043a\u0430
-ConfigTransferAutoSpeed.upload.capacity.usage=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u0443 \u0454\u043c\u043d\u0456\u0441\u0442\u044c
+ConfigTransferAutoSpeed.upload.capacity.usage=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u0443 \u043c\u0456\u0441\u0442\u043a\u0456\u0441\u0442\u044c
 ConfigTransferAutoSpeed.mode=\u0420\u0435\u0436\u0438\u043c:
-ConfigTransferAutoSpeed.capacity.used=% - \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u043d\u0430 \u043c\u0456\u0441\u0442\u043a\u0456\u0441\u0442\u044c
+ConfigTransferAutoSpeed.capacity.used=% \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f
 ConfigTransferAutoSpeed.while.downloading=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f:
 ConfigTransferAutoSpeed.set.dht.ping=\u0420\u0435\u0433\u0443\u043b\u044e\u0432\u0430\u043d\u043d\u044f \u043f\u0456\u043d\u0433\u0443 DHT:
 ConfigTransferAutoSpeed.set.point=\u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u0443\u043d\u043a\u0442 (\u043c\u0441)
@@ -2278,46 +2276,46 @@ PiecesView.DistributionView.weDownload=\u0427\u0430\u0441\u0442\u0438\u043d\u043
 PeersView.gain=\u0412\u0438\u0433\u043e\u0434\u0430
 PeersView.gain.info=\u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0445 - \u0440\u043e\u0437\u0434\u0430\u043d\u0438\u0445 \u0434\u0430\u043d\u0438\u0445
 unix.script.new.title=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439 \u043d\u043e\u0432\u0438\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0456\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 Vuze
-unix.script.new.text=\u041d\u043e\u0432\u0438\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0456\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 Vuze \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439, \u0456 \u0431\u0443\u0432 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0438\u0439 \u0432 '%1'.\n\n\u041c\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u043c\u043e \u0412\u0430\u043c \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u0438 Vuze \u0437\u0430\u0440\u0430\u0437 \u0456 \u043f\u0435\u0440\u0435\u043c\u043a\u043d\u0443\u043b\u0438\u0441\u044f \u0432 \u0446\u0435\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0456\u0439 ('%2').\n\n\u042f\u043a\u0449\u043e \u0432\u0438 \u0441\u0438\u043b\u044c\u043d\u043e \u0437\u043c\u0456\u043d\u0438\u043b\u0438 \u0432\u0430\u0448 \u0441\u0446\u0435\u043d\u0430\u0440\u0456\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 Vuze \u043f\u043e\u0434\u0438\u0432\u0456\u0442\u044c\u0441\u044f <A HREF="{unix.script.new.manual.url}">Wiki-\u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443: \u0421\u0446\u0435\u043d\u0430\u0440\u0456\u0439 Unix</A>.\n\n\u042f\u043a\u0449\u043e \u0432\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 Vuze \u0432\u0456\u0434 distro (yum, apt-get, \u0442\u043e\u0449\u043e), \u0431\u0430\u0436\u0430\u043d\u043e, \u0449\u043e\u0431 \u0432\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 Vuze, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0432\u0448\u0438 \u043f\u0430\u043a\u0435\u0442 <A HREF="http://azureus.sourceforge.net">\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0438 Vuze \u043d\u0430 Sourceforge</A> (\u0412\u0430\u0448 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u044c\u0441\u044f \u0442\u0438\u043c \u0436\u0435).
+unix.script.new.text=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0441\u0446\u0435\u043d\u0430\u0440\u0456\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 Vuze \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439, \u0456 \u0431\u0443\u0432 \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0438\u0439 \u0432 '%1'.\n\n\u041c\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u043c\u043e \u0412\u0430\u043c \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u0438 Vuze \u0437\u0430\u0440\u0430\u0437 \u0456 \u043f\u0435\u0440\u0435\u043c\u043a\u043d\u0443\u043b\u0438\u0441\u044f \u0432 \u0446\u0435\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0456\u0439 ('%2').\n\n\u042f\u043a\u0449\u043e \u0432\u0438 \u0441\u0438\u043b\u044c\u043d\u043e \u0437\u043c\u0456\u043d\u0438\u043b\u0438 \u0432\u0430\u0448 \u0441\u0446\u0435\u043d\u0430\u0440\u0456\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 Vuze \u043f\u043e\u0434\u0438\u0432\u0456\u0442\u044c\u0441\u044f <A HREF="{unix.script.new.manual.url}">Wiki-\u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443: \u0421\u0446\u0435\u043d\u0430\u0440\u0456\u0439 Unix</A>.\n\n\u042f\u043a\u0449\u043e \u0432\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 Vuze \u0432\u0456\u0434 distro (yum, apt-get, \u0442\u043e\u0449\u043e), \u0431\u0430\u0436\u0430\u043d\u043e, \u0449\u043e\u0431 \u0432\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 Vuze, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0432\u0448\u0438 \u043f\u0430\u043a\u0435\u0442 <A HREF="http://azureus.sourceforge.net">\u0421\u0442\u043e\u0440\u0456\u043d\u043a\u0438 Vuze \u043d\u0430 Sourceforge</A> (\u0412\u0430\u0448 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u044c\u0441\u044f \u0442\u0438\u043c \u0436\u0435).
 unix.script.new.button.quit=\u0412\u0438\u0439\u0442\u0438 \u0437\u0430\u0440\u0430\u0437
 unix.script.new.button.continue=\u042f \u0437\u0440\u043e\u0431\u043b\u044e \u0446\u0435 \u043f\u0456\u0437\u043d\u0456\u0448\u0435
 unix.script.new.button.asknomore=\u041d\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u044f\u0442\u0438 \u043c\u0435\u043d\u0456 \u0437\u043d\u043e\u0432\u0443
-unix.script.new.auto.title=\u041d\u043e\u0432\u0438\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0456\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 Vuze
-unix.script.new.auto.text=\u041d\u043e\u0432\u0438\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0456\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 Vuze \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439.\n\n\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 Vuze \u0437\u0430\u0440\u0430\u0437.
+unix.script.new.auto.title=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0441\u0446\u0435\u043d\u0430\u0440\u0456\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 Vuze
+unix.script.new.auto.text=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0441\u0446\u0435\u043d\u0430\u0440\u0456\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 Vuze \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439.\n\n\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0454\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 Vuze \u0437\u0430\u0440\u0430\u0437.
 Content.alert.notuploaded.button.stop=&\u0417\u0443\u043f\u0438\u043d\u0438\u0442\u0438
-Content.alert.notuploaded.button.continue=&\u041f\u0440\u043e\u0434\u043e\u0432\u0436\u0443\u0432\u0430\u0442\u0438
+Content.alert.notuploaded.button.continue=&\u041f\u0440\u043e\u0434\u043e\u0432\u0436\u0443\u0432\u0430\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0443
 Content.alert.notuploaded.button.abort=&\u041d\u0435 \u0432\u0438\u0445\u043e\u0434\u0438\u0442\u0438
-ConfigView.label.checkOnSeeding=\u0412\u0438\u043a\u043e\u043d\u0443\u0432\u0430\u0442\u0438 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0443 \u0447\u0430\u0441\u0442\u0438\u043d \u0440\u0435\u0441\u0443\u0440\u0441\u0443
+ConfigView.label.checkOnSeeding=\u0412\u0438\u043a\u043e\u043d\u0443\u0432\u0430\u0442\u0438 \u043d\u0438\u0437\u044c\u043a\u043e\u0440\u0456\u0432\u043d\u0435\u0432\u0443 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0443 \u0447\u0430\u0441\u0442\u0438\u043d \u0440\u0435\u0441\u0443\u0440\u0441\u0443
 ConfigView.label.ui_switcher=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0432\u0438\u0431\u0456\u0440 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 Vuze
 ConfigView.label.ui_switcher_button=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438
-SpeedTestWizard.test.panel.explain=\u0412\u0438\u043c\u0456\u0440\u044f\u0439\u0442\u0435 \u0441\u0432\u043e\u044e \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443. \u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0442\u0438\u043f \u0432\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0456\n\u043c\u0435\u0442\u043e\u0434 \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f. \u0412\u0456\u0434\u0432\u0456\u0434\u0430\u0439\u0442\u0435 Wiki-\u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443 Vuze \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0456\u0448\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u043f\u0440\u043e \u0432\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f. \u0412\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0443\u043f\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e, \u044f\u043a\u0449\u043e \u0442\u0440\u0438\u0432\u0430\u0442\u0438\u043c\u0435 \u0434\u043e\u0432\u0448\u0435, \u043d\u0456\u0436 \u0434\u0432\u0456 \u0445\u0432\u0438\u043b\u0438\u043d\u0438. \u0417\u0430\u0437\u0432\u0438\u0447\u0430\u0439 \u0432\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0443\u044e\u0442\u044c\u0441\u044f \u0448\u0432\u0438\u0434\u0448\u0435, \u043d\u0456\u0436 \u0437\u0430 \u0445\u0432\u0438\u043b\u0438\u043d\u0443.
-SpeedTestWizard.set.upload.hint=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0456\u0442\u044c \u043c\u0435\u0436\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u043d\u0456 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0457 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456.
-SpeedTestWizard.set.upload.panel.explain=\u041d\u0430\u0431\u0456\u0440 \u043c\u0435\u0436, \u044f\u043a\u0456 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0442\u044c\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0457 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 Vuze. \u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0456\u0442\u044c \u043c\u0435\u0436\u0456 \u043f\u0435\u0440\u0435\u0434\u0430\u0447 \u0456 \u043c\u0435\u0436\u0456 \u0434\u043e\u0432\u0456\u0440\u0438.\n\n\u0417\u0430\u0443\u0432\u0430\u0436\u0442\u0435, \u0449\u043e \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0447\u0430\u0441\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u0443\u044e\u0442\u044c\u0441\u044f \u0432 "\u0431\u0456\u0442 \u0437\u0430 \u0441\u0435\u043a\u0443\u043d\u0434\u0443" - \u043f\u0440\u043e\u0442\u0435 \u0442\u0443\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043f\u043e\u043a\u0430\u0437\u0443\u0454\u0442\u044c\u0441\u044f \u0432 "\u043a\u0456\u043b\u043e\u0431\u0430\u0439\u0442 \u0437\u0430 \u0441\u0435\u043a\u0443\u043d\u0434\u0443".
+SpeedTestWizard.test.panel.explain=\u0412\u0438\u043c\u0456\u0440\u044f\u0439\u0442\u0435 \u0441\u0432\u043e\u044e \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443. \u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0442\u0438\u043f \u0432\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0456\n\u043c\u0435\u0442\u043e\u0434 \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f. \u0412\u0456\u0434\u0432\u0456\u0434\u0430\u0439\u0442\u0435 Wiki-\u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443 Vuze \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0456\u0448\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u043f\u0440\u043e \u0432\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f. \u0412\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0443\u043f\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e, \u044f\u043a\u0449\u043e \u0442\u0440\u0438\u0432\u0430\u0442\u0438\u043c\u0435 \u0434\u043e\u0432\u0448\u0435, \u043d\u0456\u0436 \u0434\u0432\u0456 \u0445\u0432\u0438\u043b\u0438\u043d\u0438. \u0417\u0432\u0438\u0447\u0430\u0439\u043d\u043e \u0432\u0438\u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0443\u044e\u0442\u044c\u0441\u044f \u0448\u0432\u0438\u0434\u0448\u0435, \u043d\u0456\u0436 \u0437\u0430 \u0445\u0432\u0438\u043b\u0438\u043d\u0443.
+SpeedTestWizard.set.upload.hint=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0456\u0442\u044c \u043c\u0435\u0436\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f, \u044f\u043a\u0456 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0442\u044c\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0457 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456.
+SpeedTestWizard.set.upload.panel.explain=\u041d\u0430\u0431\u0456\u0440 \u043c\u0435\u0436, \u044f\u043a\u0456 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0442\u044c\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0457 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 Vuze. \u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0456\u0442\u044c \u043c\u0435\u0436\u0456 \u043f\u0435\u0440\u0435\u0434\u0430\u0447 \u0456 \u043c\u0435\u0436\u0456 \u0434\u043e\u0432\u0456\u0440\u0438.\n\n\u0417\u0430\u0443\u0432\u0430\u0436\u0442\u0435, \u0449\u043e \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0447\u0430\u0441\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u0443\u044e\u0442\u044c\u0441\u044f \u0432 "\u0431\u0456\u0442 \u0437\u0430 \u0441\u0435\u043a\u0443\u043d\u0434\u0443" - \u043f\u0440\u043e\u0442\u0435 \u0442\u0443\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f \u043f\u043e\u043a\u0430\u0437\u0443\u0454\u0442\u044c\u0441\u044f \u0432 "\u043a\u0456\u043b\u043e\u0431\u0430\u0439\u0442\u0456\u0432 \u0437\u0430 \u0441\u0435\u043a\u0443\u043d\u0434\u0443".
 SpeedTestWizard.set.limit.conf.level=\u0414\u043e\u0432\u0456\u0440\u0430
 SpeedTestWizard.finish.panel.auto.speed=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c :
 SpeedTestWizard.finish.panel.auto.speed.seeding=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c : 
-ConfigTransferAutoSpeed.add.comment.to.log.group=\u0414\u043e\u0434\u0430\u0442\u0438 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440 \u0434\u043e \u0437\u0430\u043f\u0438\u0441\u0443 \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0436\u0435\u043d\u043d\u044f
+ConfigTransferAutoSpeed.add.comment.to.log.group=\u0414\u043e\u0434\u0430\u0442\u0438 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440 \u0434\u043e \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f \u0434\u043b\u044f \u043d\u0430\u043b\u0430\u0433\u043e\u0434\u0436\u0435\u043d\u043d\u044f
 ConfigTransferAutoSpeed.add.comment.to.log=\u041a\u043e\u043c\u0435\u043d\u0442\u0430\u0440:
 ConfigTransferAutoSpeed.log.button=\u041b\u043e\u0433
 ConfigTransferAutoSpeed.algorithm.selector=\u0412\u0438\u0431\u0456\u0440 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0457 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456
-ConfigTransferAutoSpeed.algorithm=\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c:
-ConfigTransferAutoSpeed.auto.speed.classic=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c(\u043a\u043b\u0430\u0441\u0438\u0447\u043d\u0430)
-ConfigTransferAutoSpeed.auto.speed.beta=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c(\u0434\u043e\u0441\u043b\u0456\u0434\u043d\u0430)
-ConfigTransferAutoSpeed.data.update.frequency=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u0447\u0430\u0441\u0442\u043e\u0442\u0443
+ConfigTransferAutoSpeed.algorithm=\u041c\u0435\u0442\u043e\u0434:
+ConfigTransferAutoSpeed.auto.speed.classic=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c (\u043a\u043b\u0430\u0441\u0438\u0447\u043d\u0430)
+ConfigTransferAutoSpeed.auto.speed.beta=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c (\u0434\u043e\u0441\u043b\u0456\u0434\u043d\u0430)
+ConfigTransferAutoSpeed.data.update.frequency=\u0427\u0430\u0441\u0442\u043e\u0442\u0430 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
 Alert.failed.update=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u044f\u043a \u043c\u0456\u043d\u0456\u043c\u0443\u043c \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u043d\u0435\u0432\u0434\u0430\u043b\u0435. \u041f\u043e\u0434\u0438\u0432\u0456\u0442\u044c\u0441\u044f <A HREF="{Alert.failed.update.url}">AzureusWiki: \u041d\u0435\u0432\u0434\u0430\u043b\u0435 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f</A> [%1]
 OpenTorrentWindow.mb.existingFiles.partialList=(\u0427\u0430\u0441\u0442\u043a\u043e\u0432\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a.  \u0406\u0441\u043d\u0443\u0454 \u0431\u0456\u043b\u044c\u0448\u0435 \u0444\u0430\u0439\u043b\u0456\u0432)
 TableColumn.header.bad_avail_time.info=\u041e\u0441\u0442\u0430\u043d\u043d\u0456\u0439 \u0447\u0430\u0441, \u043a\u043e\u043b\u0438 \u043f\u043e\u0432\u043d\u0430 \u043a\u043e\u043f\u0456\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u044e
 TableColumn.header.bad_avail_time=\u041f\u043e\u0432\u043d\u0430 \u043a\u043e\u043f\u0456\u044f
-MyTorrentsView.menu.exporthttpseeds=\u0415\u043a\u0441\u043f\u043e\u0440\u0442\u0443\u0432\u0430\u0442\u0438 HTTP URL \u0441\u0456\u0434\u0435\u0440\u0430 \u0434\u043e \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u0431\u043c\u0456\u043d\u0443
+MyTorrentsView.menu.exporthttpseeds=\u0415\u043a\u0441\u043f\u043e\u0440\u0442\u0443\u0432\u0430\u0442\u0438 HTTP-\u0430\u0434\u0440\u0435\u0441\u0443 \u0441\u0456\u0434\u0435\u0440\u0430 \u0434\u043e \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u0431\u043c\u0456\u043d\u0443
 SWT.alert.erroringuithread=\u041d\u0435\u043a\u0435\u0440\u043e\u0432\u0430\u043d\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u0432\u0456\u0434\u0431\u0443\u0432\u0430\u043b\u0430\u0441\u044f \u0432 GUI, \u043f\u043e\u0434\u0430\u043b\u044c\u0448\u0456 \u043f\u043e\u043c\u0438\u043b\u043a\u0438, \u043c\u043e\u0436\u043b\u0438\u0432\u043e, \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u0456.
 ConfigView.label.minannounce=\u041c\u0456\u043d\u0456\u043c\u0430\u043b\u044c\u043d\u0438\u0439 \u0447\u0430\u0441 \u043c\u0456\u0436 \u0430\u043d\u043e\u043d\u0441\u0430\u043c\u0438 \u0442\u0440\u0435\u043a\u0435\u0440\u0443, \u0441
-ConfigView.label.maxnumwant=\u041b\u0456\u043c\u0456\u0442 \u043a\u0456\u043b\u044c\u043a\u043e\u0441\u0442\u0456 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432, \u044f\u043a\u0456 \u043c\u0430\u044e\u0442\u044c \u0437\u043c\u043e\u0433\u0443 \u043f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438\u0441\u044f
-ConfigView.label.announceport=\u041f\u0435\u0440\u0435\u043a\u0440\u0438\u0432\u0430\u0442\u0438 \u043f\u043e\u0440\u0442 \u0430\u043d\u043e\u043d\u0441\u0443 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+ConfigView.label.maxnumwant=\u041e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u043a\u0456\u043b\u044c\u043a\u043e\u0441\u0442\u0456 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432, \u044f\u043a\u0456 \u043c\u0430\u044e\u0442\u044c \u0437\u043c\u043e\u0433\u0443 \u043f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438\u0441\u044f
+ConfigView.label.announceport=\u041f\u0456\u0434\u043c\u0456\u043d\u044e\u0432\u0430\u0442\u0438 \u043f\u043e\u0440\u0442 \u0430\u043d\u043e\u043d\u0441\u0443 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
 ConfigView.label.noportannounce=\u041d\u0435 \u0430\u043d\u043e\u043d\u0441\u0443\u0432\u0430\u0442\u0438 \u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0443 (\u0446\u0435 \u043d\u0435 \u0432\u043f\u043b\u0438\u0432\u0430\u0454 \u043d\u0430 pex, dht)
 ConfigView.label.maxseedspertorrent=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0441\u0456\u0434\u0435\u0440\u0456\u0432 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0438\u0439] 
 wizard.webseed=\u0414\u043e\u0434\u0430\u0442\u0438 HTTP-\u0441\u0456\u0434\u0435\u0440\u0456\u0432
 wizard.webseed.title=HTTP-\u0441\u0456\u0434\u0435\u0440\u0438
-wizard.webseed.configuration=\u041a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u044f HTTP-\u0441\u0456\u0434\u0435\u0440\u0456\u0432
+wizard.webseed.configuration=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f HTTP-\u0441\u0456\u0434\u0435\u0440\u0456\u0432
 wizard.webseed.adding=\u0414\u043e\u0434\u0430\u0442\u0438 HTTP-\u0441\u0456\u0434\u0435\u0440\u0456\u0432
 GeneralView.label.private=\u041e\u0441\u043e\u0431\u0438\u0441\u0442\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442:
 GeneralView.yes=\u0422\u0430\u043a
@@ -2325,22 +2323,22 @@ GeneralView.no=\u041d\u0456
 ConfigView.label.userequestlimiting=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043f\u0440\u0438\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0439 \u0437\u0430\u043f\u0438\u0442, \u043a\u043e\u043b\u0438 \u043c\u0435\u0436\u0430 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0434\u043e\u0441\u044f\u0433\u043d\u0435\u043d\u0430 [\u043d\u0435 \u0434\u0456\u0454 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0456\u0439 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f] 
 ConfigView.label.userequestlimiting.tooltip=\u041e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f \u0437\u0430\u043f\u0438\u0442\u0443 \u043d\u0435 \u043d\u0430\u0441\u0442\u0456\u043b\u044c\u043a\u0438 \u043f\u043e\u0437\u0438\u0442\u0438\u0432\u043d\u0435, \u044f\u043a \u0437\u0434\u0430\u0454\u0442\u044c\u0441\u044f, \u0430\u043b\u0435 \u0434\u043e\u0437\u0432\u043e\u043b\u044f\u0454 \u0437\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u043d\u0430 \u043f\u043e\u0437\u0438\u0446\u0456\u0457 \u0447\u0435\u0440\u0433\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0456, \u043c\u043e\u0436\u043b\u0438\u0432\u043e, \u043f\u043e\u043b\u0456\u043f\u0448\u0443\u0454 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0438\u0432\u043d\u0456\u0441\u0442\u044c \u043c\u0435\u0440\u0435\u0436\u0456
 ConfigView.label.userequestlimitingpriorities=\u041a\u043e\u043b\u0438 \u043c\u0435\u0436\u0430 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0434\u043e\u0441\u044f\u0433\u043d\u0435\u043d\u0430, \u0437\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u0442\u0438 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u043d\u0430 \u0432\u0435\u0440\u0445\u0456\u0432\u0446\u0456 \u0447\u0435\u0440\u0433\u0438
-ConfigView.section.logging.timestamp=\u0424\u043e\u0440\u043c\u0430\u0442 \u0444\u0456\u043a\u0441\u0430\u0446\u0456\u0457 \u0447\u0430\u0441\u0443
+ConfigView.section.logging.timestamp=\u0424\u043e\u0440\u043c\u0430\u0442 \u0447\u0430\u0441\u0443
 Peers.column.timetocomplete=\u0417\u0430\u043b\u0438\u0448\u043e\u043a \u0447\u0430\u0441\u0443
 Peers.column.timetocomplete.info=\u0427\u0430\u0441, \u044f\u043a\u0438\u0439 \u0437\u0430\u043b\u0438\u0448\u0430\u0454\u0442\u044c\u0441\u044f \u0434\u043e \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0456 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
 ConfigView.section.interface.display.suppress.file.download.dialog=\u0417\u0430\u0431\u043e\u0440\u043e\u043d\u0430 \u0432\u0438\u0440\u0438\u043d\u0430\u044e\u0447\u043e\u0433\u043e \u0432\u0456\u043a\u043d\u0430 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443
 ConfigView.section.interface.display.suppress.file.download.dialog.tooltip=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0433\u0440\u0435\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443 \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 \u0441\u0442\u0430\u0442\u0443\u0441\u0443 \u0437\u0430\u043c\u0456\u0441\u0442\u044c \u0432\u0438\u0440\u0438\u043d\u0430\u044e\u0447\u043e\u0433\u043e \u0432\u0456\u043a\u043d\u0430
-FileDownload.canceled=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443 \u043e\u0440\u0435\u043d\u0442\u0443 \u0431\u0443\u043b\u043e \u0443\u0441\u043f\u0456\u0448\u043d\u043e \u0441\u043a\u0430\u0441\u043e\u0432\u0430\u043d\u043e \u0434\u0456\u0454\u044e \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430: %1
+FileDownload.canceled=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443 \u0442\u043e\u0440\u0435\u043d\u0442\u0443 \u0431\u0443\u043b\u043e \u0443\u0441\u043f\u0456\u0448\u043d\u043e \u0441\u043a\u0430\u0441\u043e\u0432\u0430\u043d\u043e \u0434\u0456\u0454\u044e \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430: %1
 Progress.reporting.status.canceled=\u0421\u043a\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u0439
-Progress.reporting.status.finished=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0439
+Progress.reporting.status.finished=\u0417\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0438\u0439
 Progress.reporting.status.retrying=\u041f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u043d\u044f...
 Progress.reporting.action.label.retry.tooltip=\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0438 \u0434\u0456\u044e
-Progress.reporting.action.label.remove.tooltip=\u0412\u0438\u0434\u0430\u043b\u0443\u0447\u0438\u0442\u0438 \u0446\u0435\u0439 \u043f\u0440\u043e\u043c\u0456\u0436\u043d\u0438\u0439 \u0437\u0432\u0456\u0442 \u0437 \u0456\u0441\u0442\u043e\u0440\u0456\u0457
+Progress.reporting.action.label.remove.tooltip=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0446\u0435\u0439 \u043f\u0440\u043e\u043c\u0456\u0436\u043d\u0438\u0439 \u0437\u0432\u0456\u0442 \u0437 \u0456\u0441\u0442\u043e\u0440\u0456\u0457
 Progress.reporting.action.label.cancel.tooltip=\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438 \u0434\u0456\u044e
-Progress.reporting.action.label.detail=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456
+Progress.reporting.action.label.detail=\u0414\u043e\u043a\u043b\u0430\u0434\u043d\u043e
 Progress.reporting.default.error=\u041d\u0435 \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u043e
-Progress.reporting.no.reports.to.display=\u041d\u0435\u043c\u0430\u0454 \u043d\u0456\u044f\u043a\u0438\u0445 \u043f\u0440\u043e\u043c\u0456\u0436\u043d\u0438\u0445 \u0437\u0432\u0456\u0442\u0456\u0432, \u0449\u043e\u0431 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0432 \u0446\u0435\u0439 \u0447\u0430\u0441.
-Progress.reporting.no.history.to.display=\u041d\u0435\u043c\u0430\u0454 \u043d\u0456\u044f\u043a\u0438\u0445 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0443.
+Progress.reporting.no.reports.to.display=\u041d\u0435\u043c\u0430 \u043d\u0456\u044f\u043a\u0438\u0445 \u043f\u0440\u043e\u043c\u0456\u0436\u043d\u0438\u0445 \u0437\u0432\u0456\u0442\u0456\u0432, \u0449\u043e\u0431 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0432 \u0446\u0435\u0439 \u0447\u0430\u0441.
+Progress.reporting.no.history.to.display=\u041d\u0435\u043c\u0430 \u043d\u0456\u044f\u043a\u0438\u0445 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0443.
 Progress.reporting.detail.history.limit=\u041c\u0435\u0436\u0430 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f (%1) \u0434\u043b\u044f \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0443 \u0431\u0443\u043b\u0430 \u043f\u0435\u0440\u0435\u0432\u0438\u0449\u0435\u043d\u0430; \u043f\u043e\u0434\u0430\u043b\u044c\u0448\u0456 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442\u044c \u0434\u043e\u0434\u0430\u043d\u0456 \u0432 \u0456\u0441\u0442\u043e\u0440\u0456\u044e
 Progress.reporting.statusbar.button.tooltip=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0432\u0456\u043a\u043d\u043e \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0443
 webui.bindip=\u0417\u0430\u0445\u043e\u043f\u043b\u0435\u043d\u043d\u044f  IP - \u043a\u043e\u043b\u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u043d\u0435 \u0437\u0430\u043f\u0438\u0442\u0430\u043d\u0438\u0439 *
@@ -2349,20 +2347,20 @@ v3.MainWindow.text.log.out=\u041f\u0456\u0434\u043f\u0438\u0441\u0430\u0442\u043
 v3.MainWindow.text.get.started=\u041f\u0456\u0434\u043f\u0438\u0441\u0430\u0442\u0438\u0441\u044f
 v3.MainWindow.text.my.account=\u041c\u0456\u0439 \u0430\u043a\u0430\u0443\u043d\u0442
 v3.MainWindow.text.my.profile=\u041f\u0440\u043e\u0444\u0456\u043b\u044c
-OpenTorrentWindow.simple.open=\u0420\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443 (\u0444\u0430\u0439\u043b, \u043b\u0456\u043d\u043a, \u0445\u0435\u0448)
-Progress.reporting.window.remove.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u043d\u0435\u0434\u0456\u044e\u0447\u0456 \u0435\u043b\u0435\u043c\u0435\u043d\u0442\u0438
+OpenTorrentWindow.simple.open=\u0420\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443 (\u0444\u0430\u0439\u043b, \u0430\u0434\u0440\u0435\u0441\u0430, \u0445\u0435\u0448)
+Progress.reporting.window.remove.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u043d\u0435\u0447\u0438\u043d\u043d\u0456 \u0435\u043b\u0435\u043c\u0435\u043d\u0442\u0438
 Progress.reporting.window.remove.auto.tooltip=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0432\u0441\u0456 \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0456, \u043d\u0435\u0432\u0434\u0430\u043b\u0456 \u0442\u0430 \u0441\u043a\u0430\u0441\u043e\u0432\u0430\u043d\u0456 \u043f\u0440\u043e\u0446\u0435\u0441\u0438
-Progress.reporting.window.remove.now=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u043d\u0435\u0434\u0456\u044e\u0447\u0456 \u0435\u043b\u0435\u043c\u0435\u043d\u0442\u0438
+Progress.reporting.window.remove.now=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u043d\u0435\u0447\u0438\u043d\u043d\u0456 \u0435\u043b\u0435\u043c\u0435\u043d\u0442\u0438
 Progress.reporting.window.remove.now.tooltip=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0432\u0441\u0456 \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u0456, \u043d\u0435\u0432\u0434\u0430\u043b\u0456 \u0442\u0430 \u0441\u043a\u0430\u0441\u043e\u0432\u0430\u043d\u0456 \u043f\u0440\u043e\u0446\u0435\u0441\u0438
-dhttracker.tracklimitedwhenonline=\u0412\u0438\u043a\u043e\u043d\u0443\u0432\u0430\u0442\u0438 \u0442\u0440\u0435\u043a\u0456\u043d\u0433 \u0440\u0435\u0441\u0443\u0440\u0441\u0443 \u0432 \u043e\u043d\u043b\u0430\u0439\u043d\u0456 \u0432\u0441\u0435-\u043e\u0434\u043d\u043e
+dhttracker.tracklimitedwhenonline=\u0412\u0438\u043a\u043e\u043d\u0443\u0432\u0430\u0442\u0438 \u043d\u0438\u0437\u044c\u043a\u043e\u0440\u0456\u0432\u043d\u0435\u0432\u0438\u0439 \u0442\u0440\u0435\u043a\u0456\u043d\u0433 \u0440\u0435\u0441\u0443\u0440\u0441\u0443 \u0432 \u043e\u043d\u043b\u0430\u0439\u043d\u0456, \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u0440\u0435\u0441\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u043e\u0442\u043e\u0447\u0435\u043d\u043d\u044f
 TorrentOptionsView.multi.title.short=\u041e\u043f\u0446\u0456\u0457 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 TorrentOptionsView.multi.title.full=\u041e\u043f\u0446\u0456\u0457 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 MyTorrentsView.menu.open_parent_folder=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0442\u0435\u043a\u0443, \u044f\u043a\u0430 \u043c\u0456\u0441\u0442\u0438\u0442\u044c
 ConfigView.section.style.use_show_parent_folder=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 "%1" \u0437\u0430\u043c\u0456\u0441\u0442\u044c "%2" \u0432 \u043c\u0435\u043d\u044e \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432
-ConfigView.section.style.use_show_parent_folder.tooltip=\u0412\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u0446\u0456\u0454\u0457 \u043e\u043f\u0446\u0456\u0457 \u0434\u043e\u0437\u0432\u043e\u043b\u044f\u0454 \u0412\u0430\u043c \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0442\u0438 \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0443 \u0442\u0435\u043a\u0443 \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0438\u0439 \u0434\u043e\u0434\u0430\u0442\u043e\u043a.\n\u041f\u0440\u043e\u0442\u0435, \u0446\u0435, \u043c\u043e\u0436\u043b\u0438\u0432\u043e, \u043e\u0437\u043d\u0430\u0447\u0430\u0454, \u0449\u043e \u0440\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043d\u0435 \u0432\u0438\u0431\u0440\u0430\u043d\u0435.
+ConfigView.section.style.use_show_parent_folder.tooltip=\u0412\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u0446\u0456\u0454\u0457 \u043e\u043f\u0446\u0456\u0457 \u0434\u043e\u0437\u0432\u043e\u043b\u044f\u0454 \u0412\u0430\u043c \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0442\u0438 \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0443 \u0442\u0435\u043a\u0443 \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0438\u0439 \u0437\u0430\u0441\u0442\u043e\u0441\u0443\u043d\u043e\u043a.\n\u041f\u0440\u043e\u0442\u0435, \u0446\u0435, \u043c\u043e\u0436\u043b\u0438\u0432\u043e, \u043e\u0437\u043d\u0430\u0447\u0430\u0454, \u0449\u043e \u0440\u043e\u0437\u0442\u0430\u0448\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043d\u0435 \u0432\u0438\u0431\u0440\u0430\u043d\u0435.
 PeerManager.status.ps_disabled=\u0414\u0436\u0435\u0440\u0435\u043b\u043e \u0443\u0447\u0430\u043d\u0438\u043a\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0435
 ConfigView.section.stats.exportfiles=\u0415\u043a\u0441\u043f\u043e\u0440\u0442\u0443\u0432\u0430\u0442\u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u043f\u0440\u043e \u0444\u0430\u0439\u043b
-updater.cant.write.to.app.title=\u041d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u0438 \u0442\u0435\u043a\u0443 \u0434\u043e\u0434\u0430\u0442\u043a\u0443
+updater.cant.write.to.app.title=\u041d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u0438 \u0442\u0435\u043a\u0443 \u0437\u0430\u0441\u0442\u043e\u0441\u0443\u043d\u043a\u0443
 updater.cant.write.to.app.details=\u0422\u0435\u043a\u0430"%1" \u043d\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0443\u0454\u0442\u044c\u0441\u044f.\n\n\u0426\u0435 \u043f\u0435\u0440\u0435\u0448\u043a\u043e\u0434\u0436\u0430\u0442\u0438\u043c\u0435 \u043c\u0430\u0439\u0431\u0443\u0442\u043d\u0456\u043c \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0431\u0435\u0437\u043f\u0435\u0447\u0435\u043d\u043d\u044f \u0431\u0443\u0442\u0438 \u0437\u0430\u0441\u0442\u043e\u0441\u043e\u0432\u0430\u043d\u0438\u043c\u0438.\n\n\u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, <a href="http://www.azureuswiki.com/index.php/Failed_Update">\u043f\u043e\u0434\u0438\u0432\u0456\u0442\u044c\u0441\u044f Wiki \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0456\u0448\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457</a>.
 plugin.install.class_version_error=\u0414\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043d\u043e\u0432\u0456\u0448\u0443 \u0432\u0435\u0440\u0441\u0456\u044e Java.
 v3.MainWindow.tab.minilibrary=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c
@@ -2383,7 +2381,7 @@ Views.plugins.aznetstatus.title=\u0421\u0442\u0430\u0442\u0443\u0441 \u043c\u043
 plugin.aznetstatus.pingtarget=\u041c\u0435\u0442\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0443 \u043f\u0456\u043d\u0433\u0443 \u0430\u0431\u043e \u0441\u043b\u0456\u0434\u0443
 ConfigView.section.style.usePathFinder=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 '\u0428\u0443\u043a\u0430\u0447\u0430 \u0448\u043b\u044f\u0445\u0443' \u0437\u0430\u043c\u0456\u0441\u0442\u044c '\u0428\u0443\u043a\u0430\u0447\u0430'
 menu.sortByColumn=\u0421\u043e\u0440\u0442\u0443\u0432\u0430\u0442\u0438 \u0437\u0430 %1 
-MyTorrentsView.menu.manual.per_peer=\u0412\u0440\u0443\u0447\u043d\u0443 (\u0437\u0430 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430)
+MyTorrentsView.menu.manual.per_peer=\u0412\u0440\u0443\u0447\u043d\u0443 (\u0434\u043b\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430)
 MyTorrentsView.menu.manual.shared_peers=\u0412\u0440\u0443\u0447\u043d\u0443 (\u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c\u0438)
 v3.button.removeActivityEntry=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u043f\u043e\u0434\u0456\u044e \u0434\u0456\u044f\u043b\u044c\u043d\u043e\u0441\u0442\u0456
 v3.splash.initSkin=\u0406\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u044f \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u043d\u044f \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443
@@ -2392,11 +2390,11 @@ OpenTorrentWindow.mb.notTorrent.cannot.display=\u041d\u0435 \u0432 \u0437\u043c\
 MainWindow.menu.window.zoom.maximize=\u0420\u043e\u0437\u0433\u043e\u0440\u043d\u0443\u0442\u0438
 MainWindow.menu.window.zoom.restore=\u0417\u043c\u0435\u043d\u0448\u0438\u0442\u0438 \u0434\u043e \u0432\u0456\u043a\u043d\u0430
 ImageResizer.image.too.small=\u0417\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0434\u0443\u0436\u0435 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0435, \u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0456\u043d\u0448\u0435 (\u044f\u043a \u043c\u0456\u043d\u0456\u043c\u0443\u043c %1 x %2)
-ImageResizer.title=\u0426\u0435\u0439 \u0456\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043e\u0437\u0432\u043e\u043b\u044f\u0454 \u0432\u0430\u043c \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u043d\u0443\u0442\u0438, \u044f\u043a \u0432\u0430\u0448 thumbnail \u0432\u0438\u0433\u043b\u044f\u0434\u0430\u0442\u0438\u043c\u0435 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0456 Vuze
+ImageResizer.title=\u0426\u0435\u0439 \u0456\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043e\u0437\u0432\u043e\u043b\u044f\u0454 \u0412\u0430\u043c \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u043d\u0443\u0442\u0438, \u044f\u043a \u0432\u0430\u0448 thumbnail \u0432\u0438\u0433\u043b\u044f\u0434\u0430\u0442\u0438\u043c\u0435 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0456 Vuze
 ImageResizer.move.image=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0456\u0442\u044c \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f, \u043f\u0435\u0440\u0435\u0442\u044f\u0433\u0443\u044e\u0447\u0438 \u0446\u0435
 ImageResizer.move.image.with.slider=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0456\u0442\u044c \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f, \u043f\u0435\u0440\u0435\u0442\u044f\u0433\u0443\u044e\u0447\u0438 \u0446\u0435, \u0437\u043c\u0456\u043d\u044e\u0439\u0442\u0435 \u0440\u043e\u0437\u043c\u0456\u0440 \u0446\u044c\u043e\u0433\u043e, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u0447\u0438 \u0441\u043b\u0430\u0439\u0434\u0435\u0440
 security.crypto.title=\u0414\u043e\u0441\u0442\u0443\u043f \u0434\u043e \u043a\u043b\u044e\u0447\u0430 \u0434\u043b\u044f \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f
-security.crypto.encrypt=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c, \u0449\u043e\u0431 \u0437\u0430\u0445\u0438\u0441\u0442\u0438\u0442\u0438 \u0432\u0430\u0448 \u043d\u0435\u0449\u043e\u0434\u0430\u0432\u043d\u043e \u0441\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0439 \u043a\u043b\u044e\u0447 \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f. \u041d\u0435 \u0437\u0430\u0431\u0443\u0432\u0430\u0439\u0442\u0435 \u0446\u0435\u0439 \u043f\u0430\u0440\u043e\u043b\u044c, \u043d\u0435\u043c\u0430\u0454 \u043d\u0456\u044f\u043a\u043e\u0457 \u043c\u043e\u0436\u043b\u0438\u0432\u043e\u0441\u0442\u0456 \u0432\u0456\u0434\u043d\u043e\u0432\u0438\u0442\u0438 \u0439\u043e\u0433\u043e!
+security.crypto.encrypt=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c, \u0449\u043e\u0431 \u0437\u0430\u0445\u0438\u0441\u0442\u0438\u0442\u0438 \u0432\u0430\u0448 \u043d\u0435\u0449\u043e\u0434\u0430\u0432\u043d\u043e \u0441\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0439 \u043a\u043b\u044e\u0447 \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f. \u041d\u0435 \u0437\u0430\u0431\u0443\u0432\u0430\u0439\u0442\u0435 \u0446\u0435\u0439 \u043f\u0430\u0440\u043e\u043b\u044c, \u043d\u0435\u043c\u0430 \u043d\u0456\u044f\u043a\u043e\u0457 \u043c\u043e\u0436\u043b\u0438\u0432\u043e\u0441\u0442\u0456 \u0432\u0456\u0434\u043d\u043e\u0432\u0438\u0442\u0438 \u0439\u043e\u0433\u043e!
 security.crypto.decrypt=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c, \u0449\u043e\u0431 \u0440\u043e\u0437\u0431\u043b\u043e\u043a\u0443\u0432\u0430\u0442\u0438 \u0432\u0430\u0448 \u043a\u043b\u044e\u0447 \u0434\u043e \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f.
 security.crypto.reason=\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0434\u043b\u044f \u0434\u0456\u0457
 security.crypto.password=\u041f\u0430\u0440\u043e\u043b\u044c
@@ -2413,7 +2411,7 @@ security.crypto.password.mismatch=\u0417\u043d\u0430\u0447\u0435\u043d\u043d\u04
 ConfigView.section.security.group.crypto=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0456 \u0456 \u043e\u0441\u043e\u0431\u0438\u0441\u0442\u0456 \u043a\u043b\u044e\u0447\u0456
 ConfigView.section.security.resetkey=\u0421\u043a\u0438\u043d\u0443\u0442\u0438 \u043a\u043b\u044e\u0447\u0456
 ConfigView.section.security.resetkey.warning.title=\u041d\u0435\u0431\u0435\u0437\u043f\u0435\u043a\u0430 \u0432\u0442\u0440\u0430\u0442\u0438 \u0434\u0430\u043d\u0438\u0445
-ConfigView.section.security.resetkey.warning=\u0412\u0438 \u0437\u0430\u043f\u0435\u0432\u043d\u044f\u0454\u0442\u0435, \u0449\u043e \u0432\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0441\u043a\u0438\u043d\u0443\u0442\u0438 \u043a\u043b\u044e\u0447\u0456 \u043a\u043e\u0434\u0443\u0432\u0430\u043d\u043d\u044f? \u042f\u043a\u0449\u043e \u0432\u0438 \u0446\u0435 \u0437\u0440\u043e\u0431\u0438\u0442\u0435, \u0432\u0441\u044f \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0430 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u0412\u0422\u0420\u0410\u0422\u0418\u0422\u042c\u0421\u042f. \u0422\u0430\u043a\u043e\u0436 \u0456\u043d\u0448\u0456 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0438 \u043d\u0435 \u0437\u043c\u043e\u0436\u0443\u0442\u044c \u043d\u0430\u0434\u0430\u043b\u0456 \u0437\u0432'\u044f\u0437\u0430\u0442\u0438\u0441\u044f \u0437 \u0412\u0430\u043c\u0438, \u043d\u0435 \u043e\u0442\u0440\u0438\u043c\u0430\u0432\u0448\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430. \u0422\u043e\u0436 \u0434\u043e\u0431\u0440\u0435 \u043f\u043e\u0434\u0443\u043c\u0430\u0439\u0442\u0435 \u0456 \u0442\u0456\u043b\u044c\u043a\u0438 \u0442\u043e\u0434\u0456 \u043f\u0440\u043e\u0434\u043e\u0432\u0436\u0443\u0439\u0442\u0435.
+ConfigView.section.security.resetkey.warning=\u0412\u0438 \u0437\u0430\u043f\u0435\u0432\u043d\u044f\u0454\u0442\u0435, \u0449\u043e \u0432\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0441\u043a\u0438\u043d\u0443\u0442\u0438 \u043a\u043b\u044e\u0447\u0456 \u0448\u0438\u0444\u0440\u0443\u0432\u0430\u043d\u043d\u044f? \u042f\u043a\u0449\u043e \u0432\u0438 \u0446\u0435 \u0437\u0440\u043e\u0431\u0438\u0442\u0435, \u0432\u0441\u044f \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0430 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u0412\u0422\u0420\u0410\u0422\u0418\u0422\u042c\u0421\u042f. \u0422\u0430\u043a\u043e\u0436 \u0456\u043d\u0448\u0456 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0438 \u043d\u0435 \u0437\u043c\u043e\u0436\u0443\u0442\u044c \u043d\u0430\u0434\u0430\u043b\u0456 \u0437\u0432'\u044f\u0437\u0430\u0442\u0438\u0441\u044f \u0437 \u0412\u0430\u043c\u0438, \u043d\u0435 \u043e\u0442\u0440\u0438\u043c\u0430\u0432\u0448\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430. \u0422\u043e\u0436 \u0434\u043e\u0431\u0440\u0435 \u043f\u043e\u0434\u0443\u043c\u0430\u0439\u0442\u0435 \u0456 \u043b\u0438\u0448\u0435 \u0442\u043e\u0434\u0456 \u043f\u0440\u043e\u0434\u043e\u0432\u0436\u0443\u0439\u0442\u0435.
 ConfigView.section.security.unlockkey=\u0412\u0456\u0434\u043c\u0438\u043a\u0430\u043d\u043d\u044f \u043a\u043b\u044e\u0447\u0456\u0432
 ConfigView.section.security.unlockkey.button=\u0412\u0456\u0434\u0456\u043c\u043a\u043d\u0443\u0442\u0438
 ConfigView.section.security.publickey=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0438\u0439 \u043a\u043b\u044e\u0447
@@ -2423,9 +2421,9 @@ ConfigView.section.security.resetkey.error=\u041d\u0435 \u0432\u0434\u0430\u043b
 ConfigView.section.security.unlockkey.error=\u041d\u0435\u0432\u0434\u0430\u043b\u043e\u0441\u044f \u0432\u0456\u0434\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043a\u043b\u044e\u0447 - \u043d\u0435\u043a\u043e\u0440\u0435\u043a\u0442\u043d\u0438\u0439 \u043f\u0430\u0440\u043e\u043b\u044c
 ConfigView.copy.to.clipboard.tooltip=\u041a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0456\u043d\u0443
 Views.plugins.azbuddy.title=\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u0456
-Browser.popup.error.no.access=\u0412\u0456\u0434\u0431\u0443\u043b\u0430\u0441\u044f \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0438\u0442\u0456 \u0440\u0435\u0441\u0443\u0440\u0441\u0443.\n\u0421\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0437\u043d\u043e\u0432\u0443 \u043f\u0456\u0437\u043d\u0456\u0448\u0435. 
+Browser.popup.error.no.access=\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0438\u0442\u0456 \u0440\u0435\u0441\u0443\u0440\u0441\u0443.\n\u0421\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0437\u043d\u043e\u0432\u0443 \u043f\u0456\u0437\u043d\u0456\u0448\u0435. 
 ConfigView.label.queue.stoponcebandwidthmet=\u041d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u0438 \u0436\u043e\u0434\u043d\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432, \u043a\u043e\u043b\u0438 \u043c\u0435\u0436\u0430 \u0448\u0432\u0438\u0434\u043a\u043e\u0441\u0442\u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u0430\u0431\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0434\u043e\u0441\u044f\u0433\u043d\u0443\u0442\u0430
-ConfigView.section.style.forceMozilla=\u0417\u043c\u0443\u0441\u0438\u0442\u0438 Vuze \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 Mozilla \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u0434\u0443 \u0432\u0456\u0434\u0436\u0435\u0442\u0456\u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 [\u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0456 xulrunner \u0430\u0431\u043e firefox 3; \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a]
+ConfigView.section.style.forceMozilla=\u0417\u043c\u0443\u0441\u0438\u0442\u0438 Vuze \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0432\u0456\u0434\u0436\u0435\u0442\u0438 Mozilla \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u0434\u0430\u0447\u0430 [\u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0456 xulrunner \u0430\u0431\u043e firefox 3; \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a]
 ConfigView.section.style.xulRunnerPath=\u0412\u043a\u0430\u0437\u0430\u0442\u0438 \u0432\u0440\u0443\u0447\u043d\u0443 \u0448\u043b\u044f\u0445 \u0434\u043e XulRunner \u0430\u0431\u043e Firefox [\u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u0434\u043b\u044f FF3; \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0443]
 azbuddy.name=\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u0456
 azbuddy.enabled=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f
@@ -2437,11 +2435,11 @@ azbuddy.addtorrent.msg=\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u044c '%1' \u0
 azbuddy.contextmenu=\u0412\u0456\u0434\u043f\u0440\u0430\u0432\u0438\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044e
 azbuddy.ui.mykey=\u041c\u0456\u0439 \u043a\u043b\u044e\u0447:
 azbuddy.ui.add=\u0414\u043e\u0434\u0430\u0442\u0438
-azbuddy.ui.new_buddy=\u041d\u043e\u0432\u0438\u0439 \u043a\u043b\u044e\u0447 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f:
+azbuddy.ui.new_buddy=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u043a\u043b\u044e\u0447 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f:
 azbuddy.ui.table.name=\u0406\u043c'\u044f
 azbuddy.ui.table.online=\u0412 \u043c\u0435\u0440\u0435\u0436\u0456
 azbuddy.ui.table.last_msg=\u041e\u0441\u0442\u0430\u043d\u043d\u0454 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f
-azbuddy.ui.menu.remove=\u041f\u0435\u0440\u0435\u043c\u0456\u0441\u0442\u0438\u0442\u0438
+azbuddy.ui.menu.remove=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438
 azbuddy.ui.menu.copypk=\u041a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438\u0439 \u043a\u043b\u044e\u0447
 azbuddy.ui.menu.send=\u041d\u0430\u0434\u0456\u0441\u043b\u0430\u0442\u0438 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f
 azbuddy.ui.menu.send_msg=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u0442\u0435\u043a\u0441\u0442, \u044f\u043a\u0438\u0439 \u0412\u0438 \u0445\u043e\u0447\u0435\u0442 \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044e(\u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f\u043c)
@@ -2465,7 +2463,7 @@ ConfigView.section.security.backupkeys.button=\u0414\u0443\u0431\u043b\u044e\u04
 ConfigView.section.security.restorekeys=\u0412\u0456\u0434\u043d\u043e\u0432\u0438\u0442\u0438 \u043a\u043b\u044e\u0447\u0456 \u0432\u0456\u0434 \u0444\u0430\u0439\u043b\u0443
 ConfigView.section.security.restorekeys.button=\u0412\u0456\u0434\u043d\u043e\u0432\u0438\u0442\u0438
 ConfigView.section.security.op.error.title=\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u0432\u0438\u043a\u043e\u043d\u0430\u0442\u0438 \u0434\u0456\u044e
-ConfigView.section.security.op.error=\u041d\u0435 \u0432\u0434\u0430\u0454\u0442\u044c\u0441\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u0442\u0438 \u0434\u0456\u044e:\n    %1
+ConfigView.section.security.op.error=\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u0442\u0438 \u0434\u0456\u044e:\n    %1
 ConfigView.section.security.restart.title=\u041d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0443
 ConfigView.section.security.restart.msg=Vuze \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u043d\u044f \u0434\u0456\u0457.
 ConfigView.section.security.system.managed=\u041a\u0435\u0440\u043e\u0432\u0430\u043d\u0438\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u044e \u0437\u0430\u0445\u0438\u0441\u0442 \u043a\u043b\u044e\u0447\u0456\u0432
@@ -2485,7 +2483,7 @@ v3.Share.header.message=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0437 \u043f
 v3.Share.add.buddy=\u0414\u043e\u0434\u0430\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456\u0432
 v3.Share.add.edit.buddy=\u0414\u043e\u0434\u0430\u0442\u0438 \u0430\u0431\u043e \u0440\u0435\u0434\u0430\u0433\u0443\u0432\u0430\u0442\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456\u0432
 v3.Share.add.buddy.all=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0437 \u0443\u0441\u0456\u043c\u0430
-v3.Share.add.buddy.existing=\u0406\u0441\u043d\u0443\u044e\u0447\u0456 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456:
+v3.Share.add.buddy.existing=\u041d\u0430\u044f\u0432\u043d\u0456 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456:
 v3.Share.add.buddy.new=\u041d\u043e\u0432\u0456 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456:
 v3.Share.buddies=\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u0456
 v3.Share.invitees=\u0417\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u0456
@@ -2501,7 +2499,7 @@ v3.MainWindow.menu.view.pluginbar=\u041f\u0430\u043d\u0435\u043b\u044c \u0456\u0
 v3.MainWindow.menu.view.buddies-viewer=\u041f\u0430\u043d\u0435\u043b\u044c \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456\u0432
 v3.activity.buddy-request=\u0412\u0430\u043c \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u043e \u0437\u0430\u043f\u0438\u0442 \u0441\u0442\u0430\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0435\u043c \u0432\u0456\u0434 %1\n\n<A HREF="%2" TARGET="minibrowse">\u0417\u0413\u041e\u0414\u0410</A>
 v3.activity.buddy-request.accept=\u0417\u0430\u0441\u0442\u043e\u0441\u0443\u0432\u0430\u0442\u0438
-v3.activity.buddy-request.multi=\u0412\u0430\u043c \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u043e \u0437\u0430\u043f\u0438\u0442 \u0441\u0442\u0430\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0435\u043c [#%3] \u0432\u0456\u0434 %1\n\n<A HREF="%2" TARGET="minibrowse">\u0417\u0413\u041e\u0414\u0410</A>
+v3.activity.buddy-request.multi=\u0412\u0430\u0445 \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u043e \u0437\u0430\u043f\u0438\u0442 \u0441\u0442\u0430\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0435\u043c [#%3] \u0432\u0456\u0434 %1\n\n<A HREF="%2" TARGET="minibrowse">\u0417\u0413\u041e\u0414\u0410</A>
 v3.activity.buddy-linkup=\u0412\u0438 \u0437 %1 \u0432\u0456\u0434\u0442\u0435\u043f\u0435\u0440 \u0441\u0442\u0430\u043b\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f\u043c\u0438
 v3.activity.share-content=%1 \u0440\u043e\u0437\u0434\u0430\u0432 %2 \u0437 \u0412\u0430\u043c\u0438\n\n\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u0432\u0456\u0434 %3:\n%4
 v3.activity.share-content.no-msg=%1 \u0440\u043e\u0437\u0434\u0430\u0432 %2 \u0437 \u0432\u0430\u043c\u0438
@@ -2512,26 +2510,26 @@ v3.buddies.add.to.share=\u0414\u043e\u0434\u0430\u0442\u0438 \u043f\u0440\u0438\
 MainWindow.dialog.select.vuze.file=\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0444\u0430\u0439\u043b Vuze
 MainWindow.menu.file.open.vuze=\u0424\u0430\u0439\u043b Vuze...
 azbuddy.ui.dialog.disable.title=\u0412\u0438\u043c\u043a\u043d\u0443\u0442\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f "\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u0456"
-azbuddy.ui.dialog.disable.text=\u0412\u0438\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f "\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u0456" \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u0435 \u043d\u0430\u0434\u0430\u0432\u0430\u0442\u0438 \u0412\u0430\u043c \u043f\u0435\u0440\u0435\u0432\u0430\u0433\u0438 \u043f\u0440\u0438 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437 \u041f\u0430\u043d\u0435\u043b\u0456 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456\u0432, \u044f\u043a\u0430 \u0437\u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0437\u043d\u0438\u0437\u0443 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u0434\u043e\u0434\u0430\u0442\u043a\u0443, \u0456 \u043d\u0435 \u0434\u0430\u0432\u0430\u0442\u0438\u043c\u0435 \u0412\u0430\u043c \u0437\u043c\u0456\u043d\u044e\u0432\u0430\u0442\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u0440\u0443\u0437\u0456\u0432.\n\n\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f?
-metasearch.addtemplate.title=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u043e\u0448\u0443\u043a \u0442\u0438\u043c\u0447\u0430\u0441\u043e\u0432\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0443?
-metasearch.addtemplate.desc=\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u0445\u043e\u0447\u0435\u0442\u0435 \u043f\u043e\u0447\u0430\u0442\u0438 \u0448\u0443\u043a\u0430\u0442\u0438 \u0442\u0438\u043c\u0447\u0430\u0441\u043e\u0432\u0438\u0439 \u0444\u0430\u0439\u043b '%1'?
+azbuddy.ui.dialog.disable.text=\u0412\u0438\u043c\u043a\u043d\u0435\u043d\u043d\u044f \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f "\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u0456" \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u0435 \u043d\u0430\u0434\u0430\u0432\u0430\u0442\u0438 \u0412\u0430\u0445 \u043f\u0435\u0440\u0435\u0432\u0430\u0433\u0438 \u043f\u0440\u0438 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0456\u0432 \u0437 \u041f\u0430\u043d\u0435\u043b\u0456 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456\u0432, \u044f\u043a\u0430 \u0437\u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0437\u043d\u0438\u0437\u0443 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u0437\u0430\u0441\u0442\u043e\u0441\u0443\u043d\u043a\u0443, \u0456 \u043d\u0435 \u0434\u0430\u0432\u0430\u0442\u0438\u043c\u0435 \u0412\u0430\u0445 \u0437\u043c\u0456\u043d\u044e\u0432\u0430\u0442\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u0440\u0443\u0437\u0456\u0432.\n\n\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f?
+metasearch.addtemplate.title=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u043e\u0448\u0443\u043a\u043e\u0432\u0438\u0439 \u0448\u0430\u0431\u043b\u043e\u043d?
+metasearch.addtemplate.desc=\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u043e\u0448\u0443\u043a\u043e\u0432\u0438\u0439 \u0448\u0430\u0431\u043b\u043e\u043d '%1'?
 v3.share.private.title=\u0420\u043e\u0437\u0434\u0430\u0447\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 v3.share.private.text=\u0412\u0438\u0431\u0440\u0430\u043d\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442 \u043f\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u044f\u043a "\u041e\u0441\u043e\u0431\u0438\u0441\u0442\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442".\n\n\u0412\u0438 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043a\u0435\u0440\u0443\u0432\u0430\u0442\u0438 \u043e\u0441\u043e\u0431\u0438\u0441\u0442\u0438\u043c\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0430\u043c\u0438.
-v3.buddies.disabled.title=\u0412\u0438\u043c\u043a\u043d\u0435\u043d\u0435 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f "\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u0456"
+v3.buddies.disabled.title=\u0412\u0438\u043c\u043a\u043d\u0443\u0442\u0435 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f "\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u0456"
 v3.buddies.disabled.text._windows=\u0412\u0438 \u0432\u0438\u043c\u043a\u043d\u0443\u043b\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f "\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u0456", \u0449\u043e \u043d\u0435 \u0434\u0430\u0432\u0430\u0442\u0438\u043c\u0435 \u0412\u0430\u043c \u0440\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u0438 \u0430\u0431\u043e \u043f\u0440\u0438\u0439\u043c\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0447\u0438 \u0437\u0430\u043f\u0438\u0442\u0438 \u0434\u0440\u0443\u0437\u0456\u0432. \u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u043c\u0456\u043d\u0438\u0442\u0438 \u0441\u0432\u043e\u0457 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 "\u041e\u043f\u0446\u0456\u0457".
 v3.buddies.disabled.text._mac=\u0412\u0438 \u0432\u0438\u043c\u043a\u043d\u0443\u043b\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f "\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u0456", \u0449\u043e \u043d\u0435 \u0434\u0430\u0432\u0430\u0442\u0438\u043c\u0435 \u0412\u0430\u043c \u0440\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u0438 \u0430\u0431\u043e \u043f\u0440\u0438\u0439\u043c\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0447\u0438 \u0437\u0430\u043f\u0438\u0442\u0438 \u0434\u0440\u0443\u0437\u0456\u0432. \u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u043c\u0456\u043d\u0438\u0442\u0438 \u0441\u0432\u043e\u0457 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 "\u041e\u043f\u0446\u0456\u0457".
-metasearch.addtemplate.dup.title=\u0414\u0443\u0431\u043b\u044e\u0432\u0430\u0442\u0438 \u0442\u0438\u043c\u0447\u0430\u0441\u043e\u0432\u0438\u0439 \u0444\u0430\u0439\u043b
-metasearch.addtemplate.dup.desc=\u041f\u043e\u0448\u0443\u043a \u0442\u0438\u043c\u0447\u0430\u0441\u043e\u0432\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0443 %1 \u0432\u0436\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439
+metasearch.addtemplate.dup.title=\u0414\u0443\u0431\u043b\u044e\u0432\u0430\u0442\u0438 \u0448\u0430\u0431\u043b\u043e\u043d
+metasearch.addtemplate.dup.desc=\u041f\u043e\u0448\u0443\u043a\u043e\u0432\u0438\u0439 \u0448\u0430\u0431\u043b\u043e\u043d %1 \u0432\u0436\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439
 metasearch.export.select.template.file=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u0448\u0430\u0431\u043b\u043e\u043d
 metasearch.import.select.template.file=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0448\u0430\u0431\u043b\u043e\u043d
 v3.MainWindow.button.newtag.share=\u041d\u043e\u0432\u0438\u0439 \u0442\u043e\u0440\u0435\u043d\u0442!
 v3.buddies.faq=\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u0438 \u0431\u0456\u043b\u044c\u0448\u0435
-dialog.uiswitch.title=\u041f\u0435\u0440\u0435\u043c\u0438\u043a\u0430\u043d\u043d\u044f \u043d\u0430 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Vuze
+dialog.uiswitch.title=\u041f\u0435\u0440\u0435\u043c\u0438\u043a\u0430\u043d\u043d\u044f \u0432 \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u043d\u044f Vuze
 dialog.uiswitch.text=\u0414\u043b\u044f \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u043d\u043d\u044f \u0446\u0456\u0454\u0457 \u043c\u043e\u0436\u043b\u0438\u0432\u043e\u0441\u0442\u0456 \u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Vuze.\n\nVuze \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f.
-dialog.uiswitch.button=\u041f\u0435\u0440\u0435\u043c\u043a\u043d\u0443\u0442\u0438\u0441\u044f \u043d\u0430 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Vuze
+dialog.uiswitch.button=\u041f\u0435\u0440\u0435\u043c\u043a\u043d\u0443\u0442\u0438  \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u043d\u044f Vuze
 azbuddy.tracker.enabled=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 '\u041f\u0440\u0438\u0441\u043a\u043e\u0440\u0435\u043d\u043d\u044f \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456\u0432' \u0434\u043b\u044f \u043f\u0440\u0456\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u043e\u0431\u043c\u0456\u043d\u0443 \u0437 \u0412\u0430\u0448\u0438\u043c\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f\u043c\u0438
 azbuddy.protocolspeed=\u0412\u0435\u0440\u0445\u043d\u044f \u043c\u0435\u0436\u0430 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f, \u041a\u0431\u0456\u0442/\u0441
-v3.MainWindow.button.download=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438
+v3.MainWindow.button.download=\u0417\u0430\u0431\u0440\u0430\u0442\u0438
 v3.MainWindow.button.run=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0439 \u0444\u0430\u0439\u043b
 v3.activity.header.friend.requests.foryou=\u0417\u0430\u043f\u0438\u0442 \u0441\u0442\u0430\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0435\u043c - \u0414\u043b\u044f \u0412\u0430\u0441
 v3.activity.header.friend.requests.fromyou=\u0417\u0430\u043f\u0438\u0442 \u0441\u0442\u0430\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0435\u043c - \u0412\u0456\u0434 \u0412\u0430\u0441
@@ -2540,21 +2538,21 @@ v3.activity.header.share.requests=\u0417\u0430\u043f\u0438\u0442\u0438 \u0440\u0
 v3.activity.header.downloads=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c
 v3.activity.header.rating.reminders=\u041d\u0430\u0433\u0430\u0434\u0443\u0432\u0430\u043d\u043d\u044f \u0440\u0435\u0439\u0442\u0438\u043d\u0433\u0443
 v3.activity.header.vuze.news=\u041d\u043e\u0432\u0438\u043d\u0438 Vuze
-login.optional.message=\u0412\u0438 \u043c\u0443\u0441\u0438\u0442\u0435 \u043f\u0456\u0434\u043f\u0438\u0441\u0430\u0442\u0438\u0441\u044f, \u0449\u043e\u0431 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0446\u044e \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c
+login.optional.message=\u0412\u0438 \u043c\u0443\u0441\u0438\u0442\u0435 \u0437\u0430\u0440\u0435\u0454\u0441\u0442\u0440\u0443\u0432\u0430\u0442\u0438\u0441\u044f, \u0449\u043e\u0431 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0446\u044e \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c
 message.confirm.share.singular=\u0427\u0443\u0434\u043e\u0432\u043e! \u0412\u0430\u0448 \u0437\u0430\u043f\u0438\u0442 \u0440\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u0438\u0439.
 message.confirm.share.plural=\u0427\u0443\u0434\u043e\u0432\u043e! \u0412\u0430\u0448 \u0437\u0430\u043f\u0438\u0442 \u0440\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u0438\u0439.
 message.confirm.share.invite.singular=\u0427\u0443\u0434\u043e\u0432\u043e! \u0412\u0430\u0448 \u0437\u0430\u043f\u0438\u0442 \u0449\u043e\u0434\u043e \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u0438\u0439.  \u0420\u043e\u0437\u0441\u043b\u0430\u0431\u0442\u0435\u0441\u044f \u0456 \u043e\u0447\u0456\u043a\u0443\u0439\u0442\u0435 \u0437\u0433\u043e\u0434\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f.
 message.confirm.share.invite.plural=\u0427\u0443\u0434\u043e\u0432\u043e! \u0412\u0430\u0448 \u0437\u0430\u043f\u0438\u0442 \u0449\u043e\u0434\u043e \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456 \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u0438\u0439.  \u0420\u043e\u0437\u0441\u043b\u0430\u0431\u0442\u0435\u0441\u044f \u0456 \u043e\u0447\u0456\u043a\u0443\u0439\u0442\u0435 \u0437\u0433\u043e\u0434\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f.
-message.confirm.invite.singular=\u0427\u0443\u0434\u043e\u0432\u043e! \u0412\u0430\u0448 \u0437\u0430\u043f\u0438\u0442 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u0438\u0439.  \u0420\u043e\u0437\u0441\u043b\u0430\u0431\u0442\u0435\u0441\u044f \u0456 \u043e\u0447\u0456\u043a\u0443\u0439\u0442\u0435 \u0437\u0433\u043e\u0434\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f.
-message.confirm.invite.plural=\u0427\u0443\u0434\u043e\u0432\u043e! \u0412\u0430\u0448 \u0437\u0430\u043f\u0438\u0442 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u0438\u0439.  \u0420\u043e\u0437\u0441\u043b\u0430\u0431\u0442\u0435\u0441\u044f \u0456 \u043e\u0447\u0456\u043a\u0443\u0439\u0442\u0435 \u0437\u0433\u043e\u0434\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f.
-message.confirm.invite.error=\u041e, \u043d\u0456! \u041d\u0430\u0441 \u0437\u0430\u043c\u043a\u043d\u0443\u043b\u043e.  \u041e\u0434\u0438\u043d \u0430\u0431\u043e \u043a\u0456\u043b\u044c\u043a\u0430 \u0412\u0430\u0441 \u043f\u043e\u043c\u0438\u043b\u0438\u043b\u0438\u0441\u044f.
+message.confirm.invite.singular=\u0427\u0443\u0434\u043e\u0432\u043e! \u0412\u0430\u0448 \u0437\u0430\u043f\u0438\u0442 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044e \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u0438\u0439.  \u0420\u043e\u0437\u0441\u043b\u0430\u0431\u0442\u0435\u0441\u044f \u0456 \u043e\u0447\u0456\u043a\u0443\u0439\u0442\u0435 \u0437\u0433\u043e\u0434\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f.
+message.confirm.invite.plural=\u0427\u0443\u0434\u043e\u0432\u043e! \u0412\u0430\u0448 \u0437\u0430\u043f\u0438\u0442 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044e \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043d\u0438\u0439.  \u0420\u043e\u0437\u0441\u043b\u0430\u0431\u0442\u0435\u0441\u044f \u0456 \u043e\u0447\u0456\u043a\u0443\u0439\u0442\u0435 \u0437\u0433\u043e\u0434\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f.
+message.confirm.invite.error=\u041e, \u043d\u0456! \u041d\u0430\u0441 \u0437\u0430\u043c\u043a\u043d\u0443\u043b\u043e.  \u041e\u0434\u043d\u0435 \u0430\u0431\u043e \u043a\u0456\u043b\u044c\u043a\u0430 \u0412\u0430\u0448\u0438\u0445 \u0437\u0430\u043f\u0438\u0442\u0456\u0432 \u043c\u0430\u044e\u0442\u044c \u043f\u043e\u043c\u0438\u043b\u043a\u0438.
 message.prompt.add.friends=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456\u0432 \u0437\u043d\u0438\u0437\u0443 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0438 \u0434\u043b\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456
 message.taking.too.long=\u041e\u0447\u0456\u043a\u0443\u0432\u0430\u043b\u043e\u0441\u044f, \u0449\u043e \u0432\u0441\u0435 \u0432\u0456\u0434\u0431\u0443\u0434\u0435\u0442\u044c\u0441\u044f \u043d\u0430\u0431\u0430\u0433\u0430\u0442\u043e \u0448\u0432\u0438\u0434\u0448\u0435\n\u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c 'ESC', \u0449\u043e\u0431 \u0441\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438 \u0446\u044e \u0434\u0456\u044e
 message.status.success=\u0423\u0441\u043f\u0456\u0448\u043d\u043e
 message.intro.friends=\u0414\u043e\u0434\u0430\u0432\u0430\u0439 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456\u0432.\n\u0420\u043e\u0437\u0434\u0430\u0432\u0430\u0439 \u0442\u043e\u0440\u0435\u043d\u0442\u0438.\n\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0439 \u0448\u0432\u0438\u0434\u0448\u0435.
 azbuddy.tracker.bbb.status.title=\u041f\u0440\u0438\u0441\u043a\u043e\u0440\u0435\u043d\u043d\u044f \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456\u0432
-azbuddy.tracker.bbb.status.title.tooltip=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u0434\u0432\u0456\u0447\u0456 \u0434\u043b\u044f \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457
-azbuddy.tracker.bbb.status.idle=\u041d\u0435\u043c\u0430\u0454 \u043f\u0440\u0438\u0441\u043a\u043e\u0440\u0435\u043d\u043d\u044f
+azbuddy.tracker.bbb.status.title.tooltip=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u0434\u0432\u0456\u0447\u0456 \u0434\u043b\u044f \u0434\u043e\u043a\u043b\u0430\u0434\u043d\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457
+azbuddy.tracker.bbb.status.idle=\u041d\u0435\u043c\u0430 \u043f\u0440\u0438\u0441\u043a\u043e\u0440\u0435\u043d\u043d\u044f
 azbuddy.tracker.bbb.status.nli=\u041d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e \u0432\u043a\u0430\u0437\u0430\u0442\u0438 \u043b\u043e\u0433\u0456\u043d
 azbuddy.tracker.bbb.status.in=\u042f \u043f\u043e\u0447\u0430\u0432 \u043f\u0440\u0438\u0441\u043a\u043e\u0440\u044e\u0432\u0430\u0442\u0438
 azbuddy.tracker.bbb.status.out=\u041f\u0440\u0438\u0441\u043a\u043e\u0440\u0435\u043d\u0456 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456
@@ -2562,14 +2560,13 @@ v3.MainWindow.search.go.tooltip=\u0412\u0438\u043a\u043e\u043d\u0430\u0442\u0438
 v3.MainWindow.search.last.tooltip=\u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438\u0441\u044f \u0434\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0456\u0432 \u043f\u043e\u0448\u0443\u043a\u0443
 v3.activity.buddy-invited=\u0412\u0438 \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043b\u0438 \u0437\u0430\u043f\u0438\u0442 \u0441\u0442\u0430\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0435\u043c \u0434\u043b\u044f %1.
 v3.activity.buddy-invited.multi=\u0412\u0438 \u043d\u0430\u0434\u0456\u0441\u043b\u0430\u043b\u0438 \u0437\u0430\u043f\u0438\u0442 \u0441\u0442\u0430\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0435\u043c \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u0438\u043c \u043b\u044e\u0434\u044f\u043c:\n%1
-metasearch.addtemplate.done.title=\u0422\u0438\u043c\u0447\u0430\u0441\u043e\u0432\u0438\u0439 \u0444\u0430\u0439\u043b \u0434\u043e\u0434\u0430\u043d\u0438\u0439
-metasearch.addtemplate.done.desc=\u0422\u0438\u043c\u0447\u0430\u0441\u043e\u0432\u0438\u0439 \u0444\u0430\u0439\u043b '%1' \u0432\u0434\u0430\u043b\u043e \u0434\u043e\u0434\u0430\u043d\u0438\u0439.\n\u0412\u0456\u043d \u0432\u0440\u0430\u0445\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u043c\u0435\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u043e\u043c\u0443 \u043f\u043e\u0448\u0443\u043a\u0443!
-v3.MainWindow.button.share=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0432\u043c\u0456\u0441\u0442
+metasearch.addtemplate.done.title=\u0428\u0430\u0431\u043b\u043e\u043d \u0434\u043e\u0434\u0430\u043d\u0438\u0439
+metasearch.addtemplate.done.desc=\u0428\u0430\u0431\u043b\u043e\u043d '%1' \u0432\u0434\u0430\u043b\u043e \u0434\u043e\u0434\u0430\u043d\u0438\u0439.\n\u0412\u0456\u043d \u0432\u0440\u0430\u0445\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u043c\u0435\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u043e\u043c\u0443 \u043f\u043e\u0448\u0443\u043a\u0443!
+v3.MainWindow.button.share=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e
 v3.buddies.remove.buddy.dialog.title=\u041f\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0436\u0435\u043d\u043d\u044f \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f
-v3.buddies.remove.buddy.dialog.text=\u0412\u0438 \u0434\u0456\u0439\u0441\u043d\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 %1 \u0437\u0456 \u0441\u043f\u0438\u0441\u043a\u0443 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456\u0432?
-ConfigView.section.style.useNewStyleMessageBox=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043d\u043e\u0432\u0438\u0439 \u0441\u0442\u0438\u043b\u044c \u0441\u043a\u0440\u0438\u043d\u044c\u043a\u0438 \u0434\u043b\u044f \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c
+v3.buddies.remove.buddy.dialog.text=\u0412\u0438 \u0434\u0456\u0439\u0441\u043d\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 %1 \u0437 \u0441\u043f\u0438\u0441\u043a\u0443 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456\u0432?
 ConfigView.section.security.nopw=\u041f\u0430\u0440\u043e\u043b\u044c \u043d\u0435 \u0437\u0430\u0431\u0435\u0437\u043f\u0435\u0447\u0443\u0454\u0442\u044c\u0441\u044f
-ConfigView.section.security.nopw_v=\u041d\u0435\u043c\u0430\u0454 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0445 \u043f\u0430\u0440\u043e\u043b\u0456\u0432, \u043f\u0456\u0434\u043f\u0438\u0448\u0456\u0442\u044c\u0441\u044f \u0432 Vuze
+ConfigView.section.security.nopw_v=\u041f\u0430\u0440\u043e\u043b\u0456 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456, \u0437\u0430\u0440\u0435\u0454\u0441\u0442\u0440\u0443\u0439\u0442\u0435\u0441\u044f \u0432 Vuze
 fileplugininstall.install.title=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f?
 fileplugininstall.install.desc=\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f '%1', \u0432\u0435\u0440\u0441\u0456\u044f %2?
 fileplugininstall.duplicate.title=\u0414\u0443\u0431\u043b\u044e\u0432\u0430\u0442\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f
@@ -2579,32 +2576,32 @@ azbuddy.os_online=\u0412 \u043c\u0435\u0440\u0435\u0436\u0456
 azbuddy.os_away=\u0412\u0456\u0434\u0441\u0443\u0442\u043d\u0456\u0439
 azbuddy.os_not_avail=\u041d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439
 azbuddy.os_busy=\u0417\u0430\u0439\u043d\u044f\u0442\u0438\u0439
-azbuddy.os_offline=\u041d\u0435 \u0432 \u043c\u0435\u0440\u0435\u0436\u0456
-azbuddy.ui.menu.disconnect=\u0412\u0456\u0434'\u0454\u0434\u043d\u0430\u043d\u0438\u0439
+azbuddy.os_offline=\u041f\u043e\u0437\u0430 \u043c\u0435\u0440\u0435\u0436\u0435\u044e
+azbuddy.ui.menu.disconnect=\u0412\u0456\u0434'\u0454\u0434\u043d\u0430\u0442\u0438
 v3.buddy.menu.chat=\u0427\u0430\u0442
-v3.chat.offline=%1 \u0437\u0430\u0440\u0430\u0437 \u043d\u0435 \u0432 \u043c\u0435\u0440\u0435\u0436\u0456 \u0456 \u043e\u0442\u0440\u0438\u043c\u0430\u0454 \u0432\u0430\u0448\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u043f\u0456\u0441\u043b\u044f \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f.
+v3.chat.offline=%1 \u0437\u0430\u0440\u0430\u0437 \u043f\u043e\u0437\u0430 \u043c\u0435\u0440\u0435\u0436\u0435\u044e \u0456 \u043e\u0442\u0440\u0438\u043c\u0430\u0454 \u0432\u0430\u0448\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u043f\u0456\u0441\u043b\u044f \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f.
 v3.chat.wrongversion=%1 \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454 \u0432\u0435\u0440\u0441\u0456\u044e Vuze, \u044f\u043a\u0430 \u043d\u0435 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454 \u0427\u0430\u0442.
 azbuddy.enable_chat_notif=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f \u0447\u0430\u0442\u0443
 v3.buddies.dnd.info.dialog.title=\u0417\u0430\u043b\u0438\u0448\u0438\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0443
-v3.buddies.dnd.info.dialog.text=\u0412\u0438 \u0432\u0438\u0431\u0440\u0430\u043b\u0438 "\u0417\u0430\u043b\u0438\u0448\u0438\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0443". \u0412\u0430\u0448 \u0432\u043c\u0456\u0441\u0442 \u043f\u0456\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u044e\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u0456 \u0435\u043a\u0440\u0430\u043d \u0432\u0456\u0434\u043a\u0440\u0438\u0454\u0442\u044c\u0441\u044f \u044f\u043a \u0442\u0456\u043b\u044c\u043a\u0438 \u0432\u0430\u0448 \u0432\u043c\u0456\u0441\u0442 \u0431\u0443\u0434\u0435 \u0433\u043e\u0442\u043e\u0432\u0438\u0439.\n\n\u041d\u0435 \u0437\u0430\u043a\u0440\u0438\u0432\u0430\u0439\u0442\u0435 Vuze, \u0449\u043e\u0431 \u0432\u0430\u0448 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044c \u043e\u0442\u0440\u0438\u043c\u0430\u0432 \u0432\u0430\u0448 \u0432\u043c\u0456\u0441\u0442.\n<A HREF="http://faq.vuze.com/?View=entry&EntryID=267">\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u0442\u0443\u0442</A> \u0434\u043b\u044f \u0434\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u043f\u0440\u043e \u0446\u044e \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c.
+v3.buddies.dnd.info.dialog.text=\u0412\u0438 \u0432\u0438\u0431\u0440\u0430\u043b\u0438 "\u0417\u0430\u043b\u0438\u0448\u0438\u0442\u0438 \u0440\u043e\u0437\u0434\u0430\u0447\u0443". \u0412\u0430\u0448\u0430 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u043f\u0456\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u044e\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0440\u043e\u0437\u0434\u0430\u0447\u0456, \u0456 \u0435\u043a\u0440\u0430\u043d \u0432\u0456\u0434\u043a\u0440\u0438\u0454\u0442\u044c\u0441\u044f, \u043a\u043e\u043b\u0438 \u0412\u0430\u0448\u0430 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u0431\u0443\u0434\u0435 \u0433\u043e\u0442\u043e\u0432\u043e\u044e.\n\n\u041d\u0435 \u0437\u0430\u043a\u0440\u0438\u0432\u0430\u0439\u0442\u0435 Vuze, \u0449\u043e\u0431 \u0432\u0430\u0448 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044c \u043e\u0442\u0440\u0438\u043c\u0430\u0432 \u0432\u0430\u0448\u0443 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e.\n<A HREF="http://faq.vuze.com/?View=entry&EntryID=267">\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u0442\u0443\u0442</A> \u0434\u043b\u044f \u0434\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u043f\u0440\u043e \u0446\u044e \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c.
 v3.buddies.dnd.info.dialog.remember=\u0411\u0456\u043b\u044c\u0448\u0435 \u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0446\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f
 progress.window.msg.progress=\u0414\u043e\u0447\u0435\u043a\u0430\u0439\u0442\u0435\u0441\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0434\u0456\u0457
 ConfigView.section.connection.advanced.read_select=\u0417\u0430\u0442\u0440\u0438\u043c\u043a\u0430 \u0447\u0438\u0442\u0430\u043d\u043d\u044f (\u043c\u0441, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e: %1)
 ConfigView.section.connection.advanced.read_select_min=\u041c\u0456\u043d\u0456\u043c\u0430\u043b\u044c\u043d\u0435 \u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u0447\u0438\u0442\u0430\u043d\u043d\u044f (\u043c\u0441, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e: %1)
-ConfigView.section.connection.advanced.write_select=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043f\u0435\u0440\u0435\u0440\u0432\u0443 \u0437\u0430\u043f\u0438\u0441\u0443 (\u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434\u0438, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e %1)
-ConfigView.section.connection.advanced.write_select_min=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043c\u0456\u043d\u0456\u043c\u0430\u043b\u044c\u043d\u0435 \u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0430\u043f\u0438\u0441\u0443 (\u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e %1)
-DetailedListView.title=\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u0438\u0439 \u0437\u0432\u0456\u0442
+ConfigView.section.connection.advanced.write_select=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f (\u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434\u0438, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e %1)
+ConfigView.section.connection.advanced.write_select_min=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043c\u0456\u043d\u0456\u043c\u0430\u043b\u044c\u043d\u0435 \u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0430\u043f\u0438\u0441\u0443\u0432\u0430\u043d\u043d\u044f (\u043c\u0456\u043b\u0456\u0441\u0435\u043a\u0443\u043d\u0434, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e %1)
+DetailedListView.title=\u0414\u043e\u043a\u043b\u0430\u0434\u043d\u0438\u0439 \u0437\u0432\u0456\u0442
 ConfigView.section.connection.network.max.outstanding.connect.attempts=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043e\u0434\u043d\u043e\u0447\u0430\u043d\u0438\u0445 \u0432\u0438\u0445\u0456\u0434\u043d\u0438\u0445 \u0437'\u0454\u0434\u043d\u0430\u043d\u044c
-plugins.init.force_enabled=Vuze \u0432\u0438\u044f\u0432\u0438\u0432 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f "%1", \u044f\u043a\u0438\u0439 \u0431\u0443\u043b\u043e \u0432\u0438\u043c\u043a\u043d\u0435\u043d\u043e - \u0446\u0435  \u0434\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e Vuze \u043f\u0440\u0430\u0446\u044e\u0432\u0430\u0442\u0438 \u043d\u0430\u043b\u0435\u0436\u043d\u0438\u043c \u0447\u0438\u043d\u043e\u043c.
-ConfigView.section.connection.prefer.udp=\u0423\u043b\u044e\u0431\u043b\u0435\u043d\u0456 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f UDP
-subscript.add.title=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0443?
-subscript.add.desc=\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0443 '%1'?
-subscript.add.dup.title=\u0414\u0443\u0431\u043b\u044e\u0432\u0430\u0442\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0443
-subscript.add.dup.desc=\u041f\u0456\u0434\u043f\u0438\u0441\u043a\u0430 '%1' \u0432\u0436\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430.
-subscript.add.upgrade.title=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0443?
-subscript.add.upgrade.desc=\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u0445\u043e\u0447\u0435\u0442\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0443 '%1'?
-subscript.add.upgradeto.desc=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0432\u0435\u0440\u0441\u0456\u044f %1 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438'%2'.\n\u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0438?
-azsubs.contextmenu.addassoc=\u0410\u0441\u043e\u0446\u0456\u044e\u0432\u0430\u0442\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438
+plugins.init.force_enabled=Vuze \u0432\u0438\u044f\u0432\u0438\u0432 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f "%1", \u044f\u043a\u0438\u0439 \u0431\u0443\u043b\u043e \u0432\u0438\u043c\u043a\u043d\u0443\u0442\u043e - \u0446\u0435  \u0434\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e Vuze \u043f\u0440\u0430\u0446\u044e\u0432\u0430\u0442\u0438 \u043d\u0430\u043b\u0435\u0436\u043d\u0438\u043c \u0447\u0438\u043d\u043e\u043c.
+ConfigView.section.connection.prefer.udp=\u041f\u0435\u0440\u0435\u0432\u0430\u0433\u0438 \u0437'\u0454\u0434\u043d\u0430\u043d\u043d\u044f\u043c UDP
+subscript.add.title=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0443?
+subscript.add.desc=\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0443 '%1'?
+subscript.add.dup.title=\u0414\u0443\u0431\u043b\u044e\u0432\u0430\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0443
+subscript.add.dup.desc=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0430 '%1' \u0432\u0436\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430.
+subscript.add.upgrade.title=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0443?
+subscript.add.upgrade.desc=\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u0445\u043e\u0447\u0435\u0442\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0443 '%1'?
+subscript.add.upgradeto.desc=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0432\u0435\u0440\u0441\u0456\u044f %1 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438'%2'.\n\u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0438?
+azsubs.contextmenu.addassoc=\u0410\u0441\u043e\u0446\u0456\u044e\u0432\u0430\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438
 azsubs.contextmenu.lookupassoc=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434 \u0430\u0441\u043e\u0446\u0456\u0430\u0446\u0456\u0439
 iconBar.start=\u041f\u043e\u0447\u0430\u0442\u0438
 iconBar.stop=\u0417\u0443\u043f\u0438\u043d\u0438\u0442\u0438
@@ -2618,34 +2615,35 @@ iconBar.bottom=\u0420\u0443\u0445\u0430\u0442\u0438 \u043d\u0430 \u0434\u043d\u0
 iconBar.queue=\u041f\u043e\u0447\u0430\u0442\u0438
 iconBar.open=\u0414\u043e\u0434\u0430\u0442\u0438 \u0442\u043e\u0440\u0435\u043d\u0442
 iconBar.share=\u0420\u043e\u0437\u0434\u0430\u0442\u0438
-iconBar.share.tooltip=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0432\u043c\u0456\u0441\u0442
-iconBar.details=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456
+iconBar.share.tooltip=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e
+iconBar.details=\u0414\u043e\u043a\u043b\u0430\u0434\u043d\u043e
 iconBar.comment=\u041a\u043e\u043c\u0435\u043d\u0442\u0430\u0440
-iconBar.play=\u0412\u0456\u0434\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f
+iconBar.play=\u0413\u0440\u0430\u0442\u0438
 iconBar.queue.tooltip=B \u0447\u0435\u0440\u0433\u0443
 v3.MainWindow.menu.view.sidebar=\u0411\u043e\u043a\u043e\u0432\u0430 \u043f\u0430\u043d\u0435\u043b\u044c
 v3.MainWindow.menu.view.actionbar=\u041f\u0430\u043d\u0435\u043b\u044c \u0434\u0456\u0439
 v3.MainWindow.menu.view.toolbars=\u041f\u0430\u043d\u0435\u043b\u0456 \u0456\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0456\u0432
 ump.install=\u0412\u0456\u0434\u0435\u043e \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0434\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0456\u0432 \u0434\u043b\u044f \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f. \u0417\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435, \u0431\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430.
-subscriptions.listwindow.title=\u0428\u0443\u043a\u0430\u0447 \u043f\u0456\u0434\u043f\u0438\u0441\u043e\u043a
-subscriptions.listwindow.autochecktext=Vuze \u043c\u043e\u0436\u0435 \u0437\u043d\u0430\u0439\u0442\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438 \u0437\u0432'\u044f\u0437\u0430\u043d\u0456 \u0437 \u0432\u043c\u0456\u0441\u0442\u043e\u043c \u0432\u0430\u0448\u043e\u0457 \u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438. \u0423\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0446\u044e \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c?
-subscriptions.listwindow.loadingtext=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434 \u043f\u0456\u0434\u043f\u0438\u0441\u043e\u043a, \u0437\u0432'\u044f\u0437\u0430\u043d\u0438\u0445 \u0437 %1
-subscriptions.listwindow.failed=\u041d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e \u043f\u0456\u0434\u043f\u0438\u0441\u043e\u043a
+subscriptions.listwindow.title=\u0428\u0443\u043a\u0430\u0447 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442
+subscriptions.listwindow.autochecktext=Vuze \u043c\u043e\u0436\u0435 \u0437\u043d\u0430\u0439\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438, \u043f\u043e\u0432'\u044f\u0437\u0430\u043d\u0456 \u0437 \u0432\u043c\u0456\u0441\u0442\u043e\u043c \u0432\u0430\u0448\u043e\u0457 \u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438. \u0423\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0446\u044e \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c?
+subscriptions.listwindow.loadingtext=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0443, \u043f\u043e\u0432'\u044f\u0437\u0430\u043d\u0438\u0445 \u0437 %1
+subscriptions.listwindow.failed=\u041d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442
 subscriptions.listwindow.popularity=\u041f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u0456\u0441\u0442\u044c
 subscriptions.listwindow.popularity.unknown=\u041d\u0435\u0432\u0456\u0434\u043e\u043c\u043e
 subscriptions.listwindow.name=\u0406\u043c'\u044f
-subscriptions.listwindow.subscribe=\u041f\u0456\u0434\u043f\u0438\u0441\u043a\u0430
-TableColumn.header.azsubs.ui.column.subs=\u041f\u0456\u0434\u043f\u0438\u0441\u043a\u0430
+subscriptions.listwindow.subscribe=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0430
+TableColumn.header.azsubs.ui.column.subs=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0430
 subscriptions.listwindow.popularity.reading=\u0427\u0438\u0442\u0430\u043d\u043d\u044f...
-PluginDeprecation.log.start=\u0426\u0435 \u0432\u0456\u043a\u043d\u043e \u043c\u0456\u0441\u0442\u0438\u0442\u044c \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u043f\u0440\u043e \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438, \u044f\u043a\u0456 \u0441\u0442\u0432\u043e\u0440\u044e\u044e\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0456\u043e\u043d\u0430\u043b\u044c\u043d\u0456\u0441\u0442\u044c, \u044f\u043a\u043e\u0457 \u043d\u0435 \u0431\u0443\u0434\u0435 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0456 \u043c\u0430\u0439\u0431\u0443\u0442\u043d\u0456\u0445 \u0432\u0435\u0440\u0441\u0456\u0439 Vuze.\n\u0412\u0430\u043c \u043d\u0435 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u0432\u0438\u043b\u0443\u0447\u0430\u0442\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438, \u0432\u0438 \u043f\u043e\u0432\u0438\u043d\u043d\u0456 \u0442\u0456\u043b\u044c\u043a\u0438 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u043d\u0430 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u0434\u043e \u043d\u0430\u0439\u043e\u0441\u0442\u0430\u043d\u043d\u0456\u0448\u043e\u0457 \u0432\u0435\u0440\u0441\u0456\u0457.\n\u042f\u043a\u0449\u043e \u0432 \u0412\u0430\u0441 \u043d\u0430\u0439\u043d\u043e\u0432\u0456\u0448\u0430 \u0432\u0435\u0440\u0441\u0456\u044f, \u0441\u043a\u043e\u043f\u0456\u044e\u0439\u0442\u0435 \u0432\u043c\u0456\u0441\u0442 \u0446\u044c\u043e\u0433\u043e \u0432\u0456\u043a\u043d\u0430 \u0456 \u0440\u043e\u0437\u043c\u0456\u0441\u0442\u0456\u0442\u044c \u0446\u0435 \u043d\u0430 \u043e\u0441\u044c \u0446\u044c\u043e\u043c\u0443 \u0444\u043e\u0440\u0443\u043c\u0456:\n \t%1\n\n
+PluginDeprecation.log.start=\u0426\u0435 \u0432\u0456\u043a\u043d\u043e \u043c\u0456\u0441\u0442\u0438\u0442\u044c \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u043f\u0440\u043e \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438, \u044f\u043a\u0456 \u0441\u0442\u0432\u043e\u0440\u044e\u044e\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0456\u043e\u043d\u0430\u043b\u044c\u043d\u0456\u0441\u0442\u044c, \u044f\u043a\u043e\u0457 \u043d\u0435 \u0431\u0443\u0434\u0435 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0456 \u043c\u0430\u0439\u0431\u0443\u0442\u043d\u0456\u0445 \u0432\u0435\u0440\u0441\u0456\u0439 Vuze.\n\u0412\u0430\u043c \u043d\u0435 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u0432\u0438\u043b\u0443\u0447\u0430\u0442\u0438 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438, \u0432\u0438 \u043f\u043e\u0432\u0438\u043d\u043d\u0456 \u043b\u0438\u0448\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u043d\u0430 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u0434\u043e \u043d\u0430\u0439\u043e\u0441\u0442\u0430\u043d\u043d\u0456\u0448\u043e\u0457 \u0432\u0435\u0440\u0441\u0456\u0457.\n\u042f\u043a\u0449\u043e \u0432 \u0412\u0430\u0441 \u043d\u0430\u0439\u043d\u043e\u0432\u0456\u0448\u0430 \u0432\u0435\u0440\u0441\u0456\u044f, \u0441\u043a\u043e\u043f\u0456\u044e\u0439\u0442\u0435 \u0432\u043c\u0456\u0441\u0442 \u0446\u044c\u043e\u0433\u043e \u0432\u0456\u043a\u043d\u0430 \u0456 \u0440\u043e\u0437\u043c\u0456\u0441\u0442\u0456\u0442\u044c \u0446\u0435 \u043d\u0430 \u043e\u0441\u044c \u0446\u044c\u043e\u043c\u0443 \u0444\u043e\u0440\u0443\u043c\u0456:\n \t%1\n\n
+PluginDeprecation.log.details=---------\n\u0406\u0414\u0415\u041d\u0422\u0418\u0424\u0406\u041a\u0410\u0422\u041e\u0420: %1\n\u0417\u041c\u0406\u0421\u0422: %2\n\n*** \u041f\u041e\u0427\u0410\u0422\u041e\u041a ***\n%3*** \u041a\u0406\u041d\u0415\u0426\u042c ***\n\n
 PluginDeprecation.view=\u0412\u0438\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c
 PluginDeprecation.alert=\u0414\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u043f\u0440\u043e\u0431\u0443\u0432\u0430\u043b\u043e \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c, \u044f\u043a\u0430 \u0431\u0443\u0434\u0435 \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u0430 \u043d\u0430\u0434\u0430\u043b\u0456, - \u0432\u0456\u0434\u043a\u0440\u0438\u0439\u0442\u0435 \u043b\u043e\u0433 \u0412\u0438\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044f \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u043d\u044f \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0456\u0448\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457.
 TableColumn.header.Thumbnail=\u041f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0430
 TableColumn.header.Thumbnail.info=\u041f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0430, \u044f\u043a\u0430 \u043f\u043e\u043a\u0430\u0437\u0443\u0454 \u0432\u043c\u0456\u0441\u0442 \u043d\u0430 Vuze; \u0434\u043b\u044f \u0432\u0441\u044c\u043e\u0433\u043e \u0456\u043d\u0448\u043e\u0433\u043e \u0432\u043c\u0456\u0441\u0442\u0443 \u0437\u0430\u0431\u0435\u0437\u043f\u0435\u0447\u0443\u0454 \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0438 \u041e\u0421.
 TableColumn.header.Rating_global=\u0420\u0435\u0439\u0442\u0438\u043d\u0433
-TableColumn.header.Rating_global.info=\u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u0435\u0439\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0443
+TableColumn.header.Rating_global.info=\u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0438\u0439 \u0440\u0435\u0439\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0446\u0456\u0454\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457
 v3.MainWindow.menu.getting_started=&\u041b\u0435\u0433\u043a\u0438\u0439 \u043f\u043e\u0447\u0430\u0442\u043e\u043a
-MainWindow.menu.community=&\u0421\u0443\u0441\u043f\u0456\u043b\u044c\u0441\u0442\u0432\u043e
+MainWindow.menu.community=\u0421\u0443\u0441\u043f\u0456&\u043b\u044c\u0441\u0442\u0432\u043e
 MainWindow.menu.help.faq=&FAQ
 MainWindow.menu.community.wiki=\u0421\u0443\u0441\u043f\u0456\u043b\u044c\u043d\u0430 &\u0432\u0456\u043a\u0456-\u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0430
 MainWindow.menu.community.forums=\u0421\u0443\u0441\u043f\u0456\u043b\u044c\u043d\u0456 \u0444\u043e&\u0440\u0443\u043c\u0438
@@ -2654,7 +2652,7 @@ MainWindow.menu.community.add_friends=&\u0414\u043e\u0434\u0430\u0442\u0438 \u04
 MainWindow.menu.help.support=&\u0414\u043e\u0432\u0456\u0434\u043a\u0430 \u0456 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0430
 externalLogin.title=\u0417\u0430\u043f\u0438\u0442 \u043b\u043e\u0433\u0456\u043d\u0443
 externalLogin.explanation=\u0428\u0430\u0431\u043b\u043e\u043d "%1" \u0432\u0438\u043c\u0430\u0433\u0430\u0454 \u0432\u043a\u0430\u0437\u0430\u0442\u0438 \u043b\u043e\u0433\u0456\u043d. \u041f\u0456\u0441\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043b\u043e\u0433\u0456\u043d\u0443 \u0432\u0456\u043a\u043d\u043e \u0437\u0430\u043a\u0440\u0438\u0454\u0442\u044c\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e.
-externalLogin.explanation.capture=\u0412\u0430\u043c \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u0432\u043a\u0430\u0437\u0430\u0442\u0438 \u043b\u043e\u0433\u0456\u043d \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0449\u043e\u0431 \u0441\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0446\u0435\u0439 \u0448\u0430\u0431\u043b\u043e\u043d.
+externalLogin.explanation.capture=\u0412\u0430\u043c \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u0432\u043a\u0430\u0437\u0430\u0442\u0438 \u043f\u0441\u0435\u0432\u0434\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0449\u043e\u0431 \u0441\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0446\u0435\u0439 \u0448\u0430\u0431\u043b\u043e\u043d.
 Button.done=\u0412\u0438\u043a\u043e\u043d\u0430\u043d\u043e
 GeneralView.torrent_created_on_and_by=%1 \u0437\u0430 %2
 v3.Share.wizard.title=\u0420\u043e\u0437\u0434\u0430\u0447\u0430 -- \u041c\u0430\u0433
@@ -2670,28 +2668,28 @@ sidebar.Library=\u041c\u043e\u044f \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0
 sidebar.LibraryDL=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 sidebar.LibraryCD=\u0412\u0438\u043a\u043e\u043d\u0430\u043d\u0456
 authenticator.location=\u041c\u0456\u0441\u0446\u0435\u0437\u043d\u0430\u0445\u043e\u0434\u0436\u0435\u043d\u043d\u044f
-authenticator.details=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456
+authenticator.details=\u0414\u043e\u043a\u043b\u0430\u0434\u043d\u043e
 v3.MainWindow.menu.publish.new=\u041f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u0442\u0438 \u043d\u043e\u0432\u0443 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e
 v3.MainWindow.menu.publish.mine=\u041e\u043f\u0443\u0431\u043b\u0456\u043a\u043e\u0432\u0430\u043d\u0430 \u0412\u0430\u043c\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f
 v3.MainWindow.menu.publish.about=\u041f\u0440\u043e \u043f\u0443\u0431\u043b\u0456\u043a\u0430\u0446\u0456\u044e...
 v3.MainWindow.menu.showActionBarText=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0442\u0435\u043a\u0441\u0442
 subscript.import.fail.title=\u041d\u0435\u0432\u0434\u0430\u043b\u0438\u0439 \u0456\u043c\u043f\u043e\u0440\u0442
-subscript.import.fail.desc=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456: %1
+subscript.import.fail.desc=\u0414\u043e\u043a\u043b\u0430\u0434\u043d\u043e: %1
 Subscription.menu.export=\u0415\u043a\u0441\u043f\u043e\u0440\u0442\u0443\u0432\u0430\u0442\u0438
-subscript.export.select.template.file=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0443
+subscript.export.select.template.file=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0443
 Button.remove=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438
-Button.send=\u041f\u043e\u0441\u043b\u0430\u0442\u0438
+Button.send=\u041d\u0430\u0434\u0456\u0441\u043b\u0430\u0442\u0438
 Button.back=\u041d\u0430\u0437\u0430\u0434
-sidebar.LibraryUnopened=\u041d\u043e\u0432\u0438\u0439
-TableColumn.header.unopened=\u041d\u043e\u0432\u0438\u0439
-Unopened.bigView.header=\u041d\u043e\u0432\u0438\u0439
+sidebar.LibraryUnopened=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438
+TableColumn.header.unopened=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438
+Unopened.bigView.header=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438
 Subscription.menu.deleteall=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0432\u0441\u0456 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0438
 Subscription.menu.reset=\u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438\u0441\u044f \u0434\u043e \u043f\u043e\u0447\u0430\u0442\u043a\u043e\u0432\u043e\u0433\u043e \u0441\u0442\u0430\u043d\u0443
-ConfigView.section.Subscriptions=\u041f\u0456\u0434\u043f\u0438\u0441\u043a\u0438
-subscriptions.config.maxresults=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0456\u0432, \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0438\u0445 \u0437\u0430 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0443 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043e]
+ConfigView.section.Subscriptions=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438
+subscriptions.config.maxresults=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0456\u0432, \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0438\u0445 \u0437\u0430 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0443 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043e]
 v3.activity.button.readall=\u041f\u043e\u0437\u043d\u0430\u0447\u0438\u0442\u0438 \u0432\u0441\u0456 \u044f\u043a \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u0456
 ConfigView.interface.start.library=\u041f\u043e\u0447\u0438\u043d\u0430\u0442\u0438 \u0432 \u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u0446\u0456
-TableColumn.header.activityNew=\u041d\u043e\u0432\u0438\u0439
+TableColumn.header.activityNew=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438
 TableColumn.header.activityType=\u0422\u0438\u043f
 TableColumn.header.activityText=\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f
 TableColumn.header.activityDate=\u0414\u0430\u0442\u0430 \u0434\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044f
@@ -2699,30 +2697,30 @@ TableColumn.header.activityActions=\u0414\u0456\u0457
 TableColumn.header.activityAvatar=\u0410\u0432\u0430\u0442\u0430\u0440
 Subscription.menu.resetauth=\u0421\u043a\u0438\u043d\u0443\u0442\u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u0456\u0434\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u0457
 Search.menu.engines=\u0428\u0430\u0431\u043b\u043e\u043d\u0438
-Wizard.Subscription.title=\u041f\u0456\u0434\u043f\u0438\u0441\u0430\u0442\u0438\u0441\u044f
-Wizard.Subscription.optin.title=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0443
+Wizard.Subscription.title=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438\u0442\u0438
+Wizard.Subscription.optin.title=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0443
 #what you've watched? Discover more with a single click...
-Wizard.Subscription.subscribe.title=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438
-Wizard.Subscription.create.title=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u043d\u043e\u0432\u0443 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0443
+Wizard.Subscription.subscribe.title=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438
+Wizard.Subscription.create.title=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u043d\u043e\u0432\u0443 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0443
 Button.search=\u041f\u043e\u0448\u0443\u043a
 Button.save=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438
 Button.add=\u0414\u043e\u0434\u0430\u0442\u0438
-Button.createNewSubscription=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u043d\u043e\u0432\u0443 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0443
-Button.availableSubscriptions=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438
-Wizard.Subscription.optin.description=\u0417 \u0443\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u043c\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0430\u043c\u0438, Vuze \u043f\u043e\u043a\u0430\u0436\u0435 \u0432\u0430\u043c \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438, \u044f\u043a\u0456 \u043c\u0430\u043b\u0438 \u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f \u0434\u043e \u0432\u043c\u0456\u0441\u0442\u0443 \u0443 \u0432\u0430\u0448\u0456\u0439 \u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u0446\u0456, \u0456 \u0434\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u0432\u0430\u043c \u0437\u043d\u0430\u0442\u0438, \u043a\u043e\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442, \u043d\u0430 \u044f\u043a\u0438\u0439 \u0412\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u0430\u043b\u0438\u0441\u044f, \u0441\u0442\u0430\u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u043c \u0434\u043b\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.\n\n\u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0443\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438?
+Button.createNewSubscription=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u043d\u043e\u0432\u0443 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0443
+Button.availableSubscriptions=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438
+Wizard.Subscription.optin.description=\u0417 \u0443\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u043c\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0430\u043c\u0438, Vuze \u043f\u043e\u043a\u0430\u0436\u0435 \u0412\u0430\u043c \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438, \u044f\u043a\u0456 \u043c\u0430\u043b\u0438 \u0432\u0456\u0434\u043d\u043e\u0448\u0435\u043d\u043d\u044f \u0434\u043e \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0443 \u0432\u0430\u0448\u0456\u0439 \u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u0446\u0456, \u0456 \u0434\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u0412\u0430\u043c \u0437\u043d\u0430\u0442\u0438, \u043a\u043e\u043b\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f, \u044f\u043a\u0443 \u0412\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438\u043b\u0438, \u0441\u0442\u0430\u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u044e \u0434\u043b\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f.\n\n\u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0443\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438?
 Wizard.Subscription.create.rss=RSS-\u0440\u043e\u0437\u0441\u0438\u043b\u043a\u0430
 Wizard.Subscription.create.search=\u041f\u043e\u0448\u0443\u043a
-Wizard.Subscription.search.subtitle1=\u0414\u043b\u044f \u0441\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f \u0432\u043b\u0430\u0441\u043d\u043e\u0457 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438 \u0432\u043a\u0430\u0436\u0456\u0442\u044c \u0457\u0457 \u0432 \u043f\u043e\u0448\u0443\u043a\u0443:
+Wizard.Subscription.search.subtitle1=\u0414\u043b\u044f \u0441\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f \u0432\u043b\u0430\u0441\u043d\u043e\u0457 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438 \u0432\u043a\u0430\u0436\u0456\u0442\u044c \u0457\u0457 \u0432 \u043f\u043e\u0448\u0443\u043a\u0443:
 Wizard.Subscription.search.subtitle2=\u0429\u043e \u043c\u043e\u0436\u0443 \u044f \u0437\u043d\u0430\u0439\u0442\u0438?
 Wizard.Subscription.search.subtitle2.sub1=\u0424\u0456\u043b\u044c\u043c\u0438 \u0432 \u0432\u0438\u0441\u043e\u043a\u043e\u043c\u0443 \u0434\u043e\u0437\u0432\u043e\u043b\u0456, \u0441\u0435\u0440\u0456\u0430\u043b\u0438, \u0448\u043e\u0443, \u0442\u0440\u0435\u0439\u043b\u0435\u0440\u0438 \u0432 \u043c\u0435\u0440\u0435\u0436\u0456 Vuze Network
 Wizard.Subscription.search.subtitle2.sub2=\u0422\u043e\u0440\u0435\u043d\u0442\u0438 \u0437 \u0443\u0441\u0456\u0445 \u0422\u0435\u043d\u0435\u0442
-Wizard.Subscription.search.subtitle3=\u042f\u043a \u0442\u0456\u043b\u044c\u043a\u0438 \u0432\u0430\u0448\u0430 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0430 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f, \u0432\u0438 \u043e\u0442\u0440\u0438\u043c\u0430\u0454\u0442\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u0456\u0439\u043d\u0456 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0431\u043e\u043a\u043e\u0432\u043e\u0457 \u043f\u0430\u043d\u0435\u043b\u0456 \u0449\u043e\u0440\u0430\u0437\u0443, \u043f\u0440\u0438 \u043d\u043e\u0432\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u0445, \u044f\u043a\u0456 \u0431\u0443\u0434\u0443\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u0434\u043b\u044f \u043f\u043e\u0448\u0443\u043a\u0443.
+Wizard.Subscription.search.subtitle3=\u041a\u043e\u043b\u0438 \u0432\u0430\u0448\u0430 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0430 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f, \u0432\u0438 \u043e\u0442\u0440\u0438\u043c\u0430\u0454\u0442\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u0456\u0439\u043d\u0456 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0431\u043e\u043a\u043e\u0432\u043e\u0457 \u043f\u0430\u043d\u0435\u043b\u0456 \u0449\u043e\u0440\u0430\u0437\u0443, \u043f\u0440\u0438 \u043d\u043e\u0432\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u0445, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0445 \u0434\u043b\u044f \u043f\u043e\u0448\u0443\u043a\u0443.
 Wizard.Subscription.rss.subtitle1=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u0430\u0434\u0440\u0435\u0441\u0443:
-Wizard.Subscription.rss.subtitle2=\u0411\u0430\u0433\u0430\u0442\u043e \u043f\u0443\u0431\u043b\u0456\u043a\u0443\u044e\u0447\u0438\u0445 \u0437\u0430\u0431\u0435\u0437\u043f\u0435\u0447\u0443\u044e\u0442\u044c \u0440\u043e\u0437\u0441\u0438\u043b\u043a\u0443 RSS \u0457\u0445 \u0432\u043c\u0456\u0441\u0442\u0443.  \u0417\u043d\u0430\u0439\u0434\u0456\u0442\u044c \u0430\u0434\u0440\u0435\u0441\u0443 \u043d\u0430 \u0441\u0430\u0439\u0442\u0456 \u043f\u0443\u0431\u043b\u0456\u043a\u0443\u044e\u0447\u043e\u0433\u043e, \u0441\u043a\u043e\u043f\u0456\u044e\u0439\u0442\u0435 \u0457\u0457 \u0456 \u0432\u0441\u0442\u0430\u0432\u0442\u0435 \u0432 \u043f\u043e\u043b\u0435, \u043d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438.
+Wizard.Subscription.rss.subtitle2=\u0411\u0430\u0433\u0430\u0442\u043e \u043f\u0443\u0431\u043b\u0456\u043a\u0443\u044e\u0447\u0438\u0445 \u0437\u0430\u0431\u0435\u0437\u043f\u0435\u0447\u0443\u044e\u0442\u044c \u0440\u043e\u0437\u0441\u0438\u043b\u043a\u0443 RSS \u0457\u0445\u043d\u044c\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457.  \u0417\u043d\u0430\u0439\u0434\u0456\u0442\u044c \u0430\u0434\u0440\u0435\u0441\u0443 \u043d\u0430 \u0441\u0430\u0439\u0442\u0456 \u043f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u043b\u044c\u043d\u043e\u0433\u043e, \u0441\u043a\u043e\u043f\u0456\u044e\u0439\u0442\u0435 \u0457\u0457 \u0456 \u0432\u0441\u0442\u0430\u0432\u0442\u0435 \u0432 \u043f\u043e\u043b\u0435, \u043d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438.
 Wizard.Subscription.rss.subtitle3=\u0417\u0431\u0435\u0440\u0456\u0433\u0448\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0443, \u0432\u0438 \u043e\u0442\u0440\u0438\u043c\u0443\u0432\u0430\u0442\u0438\u043c\u0435\u0442\u0435 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0449\u043e\u0440\u0430\u0437\u0443, \u043a\u043e\u043b\u0438 \u043d\u043e\u0432\u0456 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0438 \u043e\u0442\u0440\u0438\u043c\u0443\u0432\u0430\u0442\u0438\u043c\u0443\u0442\u044c\u0441\u044f \u0443 \u0440\u043e\u0437\u0441\u0438\u043b\u0446\u0456 RSS.
-Wizard.Subscription.subscribe.library=\u0412\u043c\u0456\u0441\u0442 \u0432\u0430\u0448\u043e\u0457 \u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438
-Wizard.Subscription.subscribe.subscriptions=\u0417\u0432'\u044f\u0437\u0430\u043d\u0456 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438
-Wizard.Subscription.subscribe.library.empty=\u041d\u0435\u043c\u0430\u0454 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0445 \u043f\u0456\u0434\u043f\u0438\u0441\u043e\u043a?\n \n\u041f\u043e\u0434\u0438\u0432\u0456\u0442\u044c\u0441\u044f \u043d\u0430 \u044f\u0441\u043a\u0440\u0430\u0432\u0443 \u043f\u043e\u043c\u0430\u0440\u0430\u043d\u0447\u0435\u0432\u0443 \u043a\u043e\u043d\u043f\u043a\u0443 \u043c\u0435\u0440\u0435\u0436\u0456 Vuze HD Network.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Read more</A>
+Wizard.Subscription.subscribe.library=\u0406\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u0432 \u0412\u0430\u0448\u0456\u0439 \u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u0446\u0456
+Wizard.Subscription.subscribe.subscriptions=\u041f\u043e\u0432'\u044f\u0437\u0430\u043d\u0456 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438
+Wizard.Subscription.subscribe.library.empty=\u041d\u0435\u043c\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0445 \u043f\u0456\u0434\u043f\u0438\u0441\u043e\u043a?\n \n\u041f\u043e\u0434\u0438\u0432\u0456\u0442\u044c\u0441\u044f \u043d\u0430 \u044f\u0441\u043a\u0440\u0430\u0432\u0443 \u043f\u043e\u043c\u0430\u0440\u0430\u043d\u0447\u0435\u0432\u0443 \u043a\u043e\u043d\u043f\u043a\u0443 \u043c\u0435\u0440\u0435\u0436\u0456 Vuze HD Network.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Read more</A>
 TableColumn.header.Info=\u0406\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f
 TableColumn.header.videoLength=\u0414\u043e\u0432\u0436\u0438\u043d\u0430 \u0432\u0456\u0434\u0435\u043e
 message.confirm.delete.title=\u041f\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0436\u0435\u043d\u043d\u044f \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u043d\u044f
@@ -2737,35 +2735,320 @@ subs.prop.num_read=\u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043f
 subs.prop.num_unread=\u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0456\u0432
 subs.prop.template=\u0428\u0430\u0431\u043b\u043e\u043d
 subs.prop.auth=\u041d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0430 \u0456\u0434\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f
-externalLogin.auth_method_proxy=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0440\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0437\u0430\u0445\u043e\u043f\u043b\u0435\u043d\u043d\u044f cookie. \u042f\u043a\u0449\u043e \u043e\u043f\u0446\u0456\u044f \u043d\u0435 \u043f\u0440\u0430\u0446\u044e\u0454, \u0432\u0438\u043c\u043a\u043d\u0456\u0442\u044c \u0457\u0457 \u0456 \u0443\u0432\u0456\u043c\u043a\u043d\u0456\u0442\u044c \u0437\u043d\u043e\u0432\u0443
+externalLogin.auth_method_proxy=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u0440\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0437\u0430\u0445\u043e\u043f\u043b\u0435\u043d\u043d\u044f cookie. \u042f\u043a\u0449\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043d\u0435 \u043f\u0440\u0430\u0446\u044e\u0454, \u0432\u0438\u043c\u043a\u043d\u0456\u0442\u044c \u0439\u043e\u0433\u043e \u0456 \u0443\u0432\u0456\u043c\u043a\u043d\u0456\u0442\u044c \u0437\u043d\u043e\u0432\u0443
 externalLogin.wait=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f, \u0437\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435, \u0431\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430...
 TableColumn.menu.date_added.time=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0447\u0438 \u043f\u0440\u0438\u0445\u043e\u0432\u0430\u0442\u0438 \u0447\u0430\u0441
-sidebar.VuzeHDNetwork=Vuze HD Network
+sidebar.VuzeHDNetwork=\u041c\u0435\u0440\u0435\u0436\u0430 Vuze HD Network
 subs.prop.next_scan=\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u0435 \u0441\u043a\u0430\u043d\u0443\u0432\u0430\u043d\u043d\u044f
 subs.prop.assoc=\u0410\u0441\u043e\u0446\u0456\u0430\u0446\u0456\u0457
 subs.prop.version=\u0412\u0435\u0440\u0441\u0456\u044f
 subscriptions.column.new.info=\u041f\u043e\u043a\u0430\u0437\u0443\u0454 \u043d\u0430\u044f\u0432\u043d\u0456\u0441\u0442\u044c \u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0431\u043e \u0431\u0456\u043b\u044c\u0448\u043e\u0457 \u043a\u0456\u043b\u044c\u043a\u043e\u0441\u0442\u0456 \u043d\u043e\u0432\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0456\u0432
-subscriptions.column.name=\u041f\u0456\u0434\u043f\u0438\u0441\u043a\u0430
+subscriptions.column.name=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0430
 subscriptions.column.nb-results=\u0417\u0430\u0433\u0430\u043b\u044c\u043d\u0456
 subscriptions.column.nb-new-results=\u041d\u043e\u0432\u0456 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0438
 subscriptions.column.last-checked=\u041e\u0441\u0442\u0430\u043d\u043d\u0456 \u043f\u0435\u0440\u0435\u0432\u0456\u0440\u0435\u043d\u0456
-subscriptions.view.title=\u041f\u0456\u0434\u043f\u0438\u0441\u043a\u0438
+subscriptions.view.title=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438
 subs.prop.is_public=\u0421\u0443\u0441\u043f\u0456\u043b\u044c\u043d\u0438\u0439
 subs.prop.high_version=\u0414\u043e\u0434\u0430\u043d\u0430 \u043e\u0441\u0442\u0430\u043d\u043d\u044f \u0432\u0435\u0440\u0441\u0456\u044f
 Subscription.menu.upgrade=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0434\u043e \u043d\u043e\u0432\u0456\u0448\u043e\u0457 \u0432\u0435\u0440\u0441\u0456\u0457
-metasearch.template.version.bad=\u041f\u043e\u0448\u0443\u043a\u043e\u0432\u0438\u0439 \u0448\u0430\u0431\u043b\u043e\u043d '%1' \u043d\u0435 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439, \u0434\u043e\u043a\u0438 \u0432\u0438 \u043d\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0435 Vuze
-metasearch.addtemplate.failed.title=\u0417\u0431\u0456\u0439 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0456
-metasearch.addtemplate.failed.desc=\u0417\u0431\u0456\u0439 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0456 \u043f\u043e\u0448\u0443\u043a\u043e\u0432\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0443: %1
-subscription.version.bad=\u041f\u0456\u0434\u043f\u0438\u0441\u043a\u0430 '%1' \u043d\u0435 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430, \u0434\u043e\u043a\u0438 \u0432\u0438 \u043d\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0435 Vuze
-statusbar.feedback=\u041f\u043e\u0441\u043b\u0430\u0442\u0438 \u0437\u0432\u043e\u0440\u043e\u0442\u043d\u0454 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f
+metasearch.template.version.bad=\u041f\u043e\u0448\u0443\u043a\u043e\u0432\u0438\u0439 \u0448\u0430\u0431\u043b\u043e\u043d '%1' \u043d\u0435 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439, \u043f\u043e\u043a\u0438 \u0432\u0438 \u043d\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0435 Vuze
+metasearch.addtemplate.failed.title=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0456
+metasearch.addtemplate.failed.desc=\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0456 \u043f\u043e\u0448\u0443\u043a\u043e\u0432\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0443: %1
+subscription.version.bad=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0430 '%1' \u043d\u0435 \u043c\u043e\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430, \u043f\u043e\u043a\u0438 \u0432\u0438 \u043d\u0435 \u043f\u043e\u043d\u043e\u0432\u0438\u0442\u0435 Vuze
+statusbar.feedback=\u041d\u0430\u0434\u0456\u0441\u043b\u0430\u0442\u0438 \u0437\u0432\u043e\u0440\u043e\u0442\u043d\u0454 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f
 statusbar.feedback.tooltip=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u0442\u0443\u0442, \u0449\u043e\u0431 \u043f\u043e\u0441\u043b\u0430\u0442\u0438 \u0437\u0432\u043e\u0440\u043e\u0442\u043d\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f
 sidebar.Activity=\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f
 v3.activity.button.watchall=\u041f\u043e\u0437\u043d\u0430\u0447\u0438\u0442\u0438 \u0432\u0441\u0456 \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u043d\u0443\u0442\u0438\u043c\u0438
-subscriptions.view.help.1=\u0414\u043e\u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438
-subscriptions.view.help.2=\u041e\u0442\u0440\u0438\u043c\u0443\u0439\u0442\u0435 \u0431\u0435\u0437\u043a\u043e\u0448\u0442\u043e\u0432\u043d\u0456 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432\u0456\u0434\u0440\u0430\u0437\u0443, \u044f\u043a \u0442\u0456\u043b\u044c\u043a\u0438 \u043d\u043e\u0432\u0438\u0439 \u0432\u043c\u0456\u0441\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u0439 \u0434\u043b\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">\u0427\u0438\u0442\u0430\u0442\u0438 \u0431\u0456\u043b\u044c\u0448\u0435</A>.
+subscriptions.view.help.1=\u0414\u043e\u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438
+subscriptions.view.help.2=\u041e\u0442\u0440\u0438\u043c\u0443\u0439\u0442\u0435 \u0431\u0435\u0437\u043a\u043e\u0448\u0442\u043e\u0432\u043d\u0456 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432\u0456\u0434\u0440\u0430\u0437\u0443, \u043a\u043e\u043b\u0438 \u043d\u043e\u0432\u0430 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0434\u043b\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">\u0427\u0438\u0442\u0430\u0442\u0438 \u0431\u0456\u043b\u044c\u0448\u0435</A>.
 sidebar.sash.tooltip=F7 \u043f\u043e\u043a\u0430\u0437\u0443\u0454 \u0456 \u0441\u043f\u0440\u0438\u0445\u043e\u0432\u0443\u0454 \u0431\u043e\u043a\u043e\u0432\u0443 \u043f\u0430\u043d\u0435\u043b\u044c
 sidebar.expand.tooltip=\u0420\u043e\u0437\u0448\u0438\u0440\u0438\u0442\u0438 \u0431\u043e\u043a\u043e\u0432\u0443 \u043f\u0430\u043d\u0435\u043b\u044c
 sidebar.dropdown.tooltip=\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0431\u043e\u043a\u043e\u0432\u0443 \u043f\u0430\u043d\u0435\u043b\u044c \u044f\u043a \u043c\u0435\u043d\u044e
-subscript.all.subscribed=\u0412\u0438 \u043f\u0456\u0434\u043f\u0438\u043f\u0438\u0441\u0430\u043d\u0456 \u043d\u0430 \u0446\u0435\u0439 \u0432\u043c\u0456\u0441\u0442
-subscript.some.subscribed=\u0412\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u0430\u043d\u0456 \u043d\u0430 \u0434\u0435\u044f\u043a\u0456 \u0437 \u043f\u0456\u0434\u043f\u0438\u0441\u043e\u043a \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0432\u043c\u0456\u0441\u0442\u0443.\n\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u0431\u0430\u0447\u0438\u0442\u0438 \u043d\u0448\u0456 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438
-subscript.none.subscribed=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u0431\u0430\u0447\u0438\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u043f\u0456\u0434\u043f\u0438\u0441\u043a\u0438 \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0432\u043c\u0456\u0441\u0442\u0443
+subscript.all.subscribed=\u0412\u0438 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438\u043b\u0438 \u0446\u044e \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e
+subscript.some.subscribed=\u0412\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u0430\u043d\u0456 \u043d\u0430 \u0434\u0435\u044f\u043a\u0456 \u0437 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442 \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0432\u043c\u0456\u0441\u0442\u0443.\n\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u0431\u0430\u0447\u0438\u0442\u0438 \u043d\u0448\u0456 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438
+subscript.none.subscribed=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u0431\u0430\u0447\u0438\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438 \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0432\u043c\u0456\u0441\u0442\u0443
+v3.iconBar.up.tooltip=\u0414\u043e\u0433\u043e\u0440\u0438\n\u0417\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u043c\u0438\u0448\u0456 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0456\u0449\u0435\u043d\u043d\u044f \u0434\u043e\u0433\u043e\u0440\u0438
+v3.iconBar.down.tooltip=\u0414\u043e\u043d\u0438\u0437\u0443\n\u0417\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u043c\u0438\u0448\u0456 \u0434\u043b\u044f \u0440\u0443\u0445\u0443 \u0434\u043e\u043d\u0438\u0437\u0443
+TableColumn.header.azsubs.ui.column.subs_link=\u0410\u0441\u043e\u0446\u0456\u0430\u0446\u0456\u044f
+TableColumn.header.azsubs.ui.column.subs_link.info=\u0410\u0441\u043e\u0446\u0456\u044e\u0432\u0430\u0442\u0438 \u0437 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0430\u043c\u0438
+Button.deleteContent.fromLibrary=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0437 \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438
+Button.deleteContent.fromComputer=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0437 \u043a\u043e\u043c\u043f'\u044e\u0442\u0435\u0440\u0430
+v3.deleteContent.message=\n\u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 '%1' \u0437 \u043a\u043e\u043c\u043f'\u044e\u0442\u0435\u0440\u0430, \u0447\u0438 \u043b\u0438\u0448\u0435 \u0437 \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438 Vuze?
+v3.library.infobar.text1=\u0428\u0443\u043a\u0430\u0454\u0442\u0435 \u0440\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u0432\u0438\u0433\u043b\u044f\u0434?
+v3.library.infobar.text2=\u041f\u0435\u0440\u0435\u043c\u043a\u043d\u0443\u0442\u044c \u0432\u0438\u0433\u043b\u044f\u0434 \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456, \u044f\u043a\u0430 \u0437\u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432\u0438\u0449\u0435.
+v3.MainWindow.menu.view.toolbartext=\u041f\u0456\u0434\u043f\u0438\u0441\u0443\u0432\u0430\u0442\u0438 \u043f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0438
+v3.MainWindow.menu.view.asSimpleList=\u041f\u0440\u043e\u0441\u0442\u0438\u0439 \u043f\u0435\u0440\u0435\u043b\u0456\u043a
+v3.MainWindow.menu.view.asAdvancedList=\u0420\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u043b\u0456\u043a
+v3.MainWindow.menu.view.statusbar=\u0420\u044f\u0434\u043e\u043a \u0441\u0442\u0430\u043d\u0443
+Subscription.menu.dirtyall=\u041f\u043e\u0437\u043d\u0430\u0447\u0438\u0442\u0438 \u0432\u0441\u0456 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0438 \u044f\u043a \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u0456
+configureWizard.file.message3=Vuze \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0443\u0432\u0430\u0442\u0438\u043c\u0435 \u0444\u0430\u0439\u043b\u0438 \u0432 \u043f\u0435\u0432\u043d\u0443 \u0442\u0435\u043a\u0443, \u044f\u043a\u0443 \u043c\u043e\u0436\u043d\u0430 \u0432\u0438\u0431\u0440\u0430\u0442\u0438 \u0442\u0443\u0442:
+v3.deleteContent.applyToAll=\u0417\u0430\u0441\u0442\u043e\u0441\u0443\u0432\u0430\u0442\u0438 \u0434\u0456\u044e \u0434\u043e \u0443\u0441\u0456\u0445 %1 \u0432\u0438\u0431\u0440\u0430\u043d\u0438\u0445 \u0437\u0430\u043f\u0438\u0441\u0456\u0432
+ConfigView.label.seeding.firstPriority.ignoreIdleHours=\u0422\u043e\u0440\u0435\u043d\u0442\u0438, \u044f\u043a\u0456 \u043d\u0435 \u0440\u043e\u0437\u0434\u0430\u044e\u0442\u044c\u0441\u044f
+v3.MainWindow.menu.contentnetworks=&\u041c\u0435\u0440\u0435\u0436\u0456 HD Networks
+v3.MainWindow.menu.contentnetworks.about=\u041f\u0440\u043e \u043c\u0435\u0440\u0435\u0436\u0456 HD Networks
+Peers.column.as=A\u0421/A\u0421\u041d
+Peers.column.as.info=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 A\u0421 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 (\u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0457 \u0441\u0438\u0441\u0442\u0435\u043c\u0438)
+ConfigTransferAutoSpeed.auto.speed.neural=\u041d\u0435\u0440\u0432\u043e\u0432\u0430 (\u0410\u043b\u044c\u0444\u0430\u0433\u0443\u0434\u0456)
+ConfigView.label.autoopen.downloadbars=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0442\u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f, \u043a\u043e\u043b\u0438
+ConfigView.label.autoopen=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0435 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0442\u044f
+ConfigView.label.autoopen.detailstab=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0442\u0438 \u041f\u0430\u043d\u0435\u043b\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c, \u043a\u043e\u043b\u0438
+ConfigView.label.systray=\u0421\u0438\u0441\u0442\u0435\u043c\u043d\u0438\u0439 \u0442\u0440\u0435\u0439
+ConfigView.label.systray._mac=\u041f\u0456\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u0430 \u0440\u044f\u0434\u043a\u0430 \u0441\u0442\u0430\u043d\u0443
+ConfigView.section.interface.legacy=\u0421\u043f\u0430\u0434\u043e\u043a
+v3.MainWindow.menu.contentnetworks.manage=&\u041a\u0435\u0440\u0443\u0432\u0430\u0442\u0438 \u043c\u0435\u0440\u0435\u0436\u0430\u043c\u0438 HD Networks
+azbuddy.ui.table.loc_cat=\u041a\u0430\u0442. \u0432\u0456\u0434\u043a.
+azbuddy.ui.table.rem_cat=\u041a\u0430\u0442. \u043f\u0440.
+azbuddy.ui.menu.cat=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457
+azbuddy.ui.menu.cat.share=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438\u0442\u0438 \u0437 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0435\u043c
+azbuddy.ui.menu.cat.set=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457
+azbuddy.ui.menu.cat.set_msg=\u0421\u043f\u0438\u0441\u043e\u043a \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0439 \u0440\u043e\u0437\u0434\u0456\u043b\u044f\u0454\u0442\u044c\u0441\u044f \u043a\u043e\u043c\u0430\u043c\u0438
+azbuddy.ui.menu.cat_subs=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0430
+v3.buddy.prop.dn=\u0406\u043c'\u044f, \u044f\u043a\u0435 \u043f\u043e\u043a\u0430\u0437\u0443\u0454\u0442\u044c\u0441\u044f
+v3.buddy.prop.un=\u0406\u043c'\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430
+v3.buddy.prop.on=\u0412 \u043c\u0435\u0440\u0435\u0436\u0456
+v3.buddy.prop.lupd=\u0412\u043e\u0441\u0442\u0430\u043d\u043d\u0454 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043e
+v3.buddy.prop.pks=\u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u043f\u0443\u0431\u043b\u0456\u0447\u043d\u0438\u0445 \u043a\u043b\u044e\u0447\u0456\u0432
+v3.buddy.prop.pc=\u041e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c
+v3.buddy.prop.catout=\u0412\u0430\u0448\u0456 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457, \u044f\u043a\u0456 \u043c\u043e\u0436\u0435 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044c
+v3.buddy.prop.catin=\u0412\u0430\u043c \u0437\u0430\u043f\u0440\u043e\u043f\u043e\u043d\u043e\u0432\u0430\u043d\u0456 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f
+v3.buddy.set.catout=\u0414\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044e \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438\u0442\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u044e
+v3.buddy.set.catin=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438\u0442\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u044e \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u044f
+subs.prop.update_period=\u041f\u0435\u0440\u0456\u043e\u0434 \u043f\u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f
+azbuddy.enable_cat_pub=\u0421\u0443\u0441\u043f\u0456\u043b\u044c\u043d\u0456 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457, \u043d\u0430 \u044f\u043a\u0456 \u0412\u0421\u0406 \u0432\u0430\u0448\u0456 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456 \u043c\u043e\u0436\u0443\u0442\u044c \u043f\u0456\u0434\u043f\u0438\u0441\u0430\u0442\u0438\u0441\u044f (\u0440\u043e\u0437\u0434\u0456\u043b\u044f\u0442\u0438 ',') 
+v3.dialog.cnclose.title=%1 \u0437\u0430\u043a\u0440\u0438\u0442\u0438\u0439
+v3.dialog.cnclose.subtitle=\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u043d\u044f
+v3.dialog.cnclose.info1=\u0412\u0438 \u0437\u0430\u043a\u0440\u0438\u043b\u0438 \u043c\u0435\u0440\u0435\u0436\u0443 HD Network
+v3.dialog.cnclose.info2=\u042f\u043a\u0449\u043e \u0412\u0438 \u0437\u0430\u0431\u0430\u0436\u0430\u0454\u0442\u0435 \u0437\u043d\u043e\u0432\u0443 \u0432\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0446\u044e \u043c\u0435\u0440\u0435\u0436\u0443 HD Network, \u0441\u043a\u043e\u0440\u0438\u0441\u0442\u0430\u0439\u0442\u0435\u0441\u044f \u043c\u0435\u043d\u044e "\u041c\u0435\u0440\u0435\u0436\u0456 HD Networks"
+v3.dialog.cnclose.noshow=\u0411\u0456\u043b\u044c\u0448\u0435 \u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438
+v3.dialog.cnmanage.title=\u041c\u0435\u043d\u044e \u043a\u0435\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u043c\u0435\u0440\u0435\u0436\u0430\u043c\u0438 HD Networks
+v3.dialog.cnmanage.intro=\u0423 \u0441\u043f\u0438\u0441\u043a\u0443, \u044f\u043a\u0438\u0439 \u0437\u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u043d\u0438\u0436\u0447\u0435, \u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0438\u0431\u0440\u0430\u0442\u0438 \u043c\u0435\u0440\u0435\u0436\u0456, \u044f\u043a\u0456 \u0431\u0430\u0436\u0430\u0454\u0442\u0435 \u0431\u0430\u0447\u0438\u0442\u0438 \u0432 \u043c\u0435\u043d\u044e "\u041c\u0435\u0440\u0435\u0436\u0456 HD Networks"
+azbuddy.ui.table.read_cat=\u0427\u0438\u0442. \u043a\u0430\u0442.
+TableColumn.header.#.info=\u041f\u043e\u0437\u0438\u0446\u0456\u044f \u0430\u0431\u043e \u043d\u043e\u043c\u0435\u0440 \u0437\u0430\u043c\u043e\u0432\u043b\u0435\u043d\u043d\u044f
+TableColumn.header.category.info=\u041d\u0430\u0437\u0432\u0430 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457, \u0434\u043e \u044f\u043a\u043e\u0457 \u043d\u0430\u043b\u0435\u0436\u0438\u0442\u044c \u0442\u043e\u0440\u0435\u043d\u0442
+TableColumn.header.DateCompleted.info=\u0414\u0430\u0442\u0430 \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0443
+TableColumn.header.AzProduct.info=\u0422\u043e\u0440\u0435\u043d\u0442 \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043e \u0437 \u043c\u0435\u0440\u0435\u0436\u0456
+TableColumn.header.health.info=\u041d\u0430\u0441\u043a\u0456\u043b\u044c\u043a\u0438 \u0436\u0438\u0442\u0442\u0454\u0437\u0434\u0430\u0442\u043d\u0435 \u0432\u0430\u0448\u0435 \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0434\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0443
+TableColumn.header.Info.info=\u041a\u043d\u043e\u043f\u043a\u0430, \u044f\u043a\u0430 \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0454 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c \u0432\u043c\u0456\u0441\u0442\u0443 Vuze
+TableColumn.header.maxuploads.info=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c # \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0447\u0430\u0441\u043d\u043e\u0457 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
+TableColumn.header.name.info=\u0406\u043c'\u044f \u0442\u043e\u0440\u0435\u043d\u0442\u0430
+TableColumn.header.unopened.info=\u041f\u043e\u0437\u043d\u0430\u0447\u043a\u0430, \u044f\u043a\u0430 \u0432\u043a\u0430\u0437\u0443\u0454, \u0449\u043e \u0442\u043e\u0440\u0435\u043d\u0442 \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u044e\u0432\u0430\u0432\u0441\u044f (\u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0432\u0441\u044f)
+TableColumn.header.Quality.info=\u042f\u043a\u0456\u0441\u0442\u044c \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 (\u043d\u0430\u043f\u0440\u0438\u043a\u043b\u0430\u0434 HD, SD)
+TableColumn.header.RateIt.info=\u0417\u0434\u0430\u0442\u043d\u0456\u0441\u0442\u044c \u043e\u0446\u0456\u043d\u0438\u0442\u0438 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e
+TableColumn.header.savepath.info=\u0422\u0435\u043a\u0430 \u0430\u0431\u043e \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0442\u043e\u0440\u0435\u043d\u0442\u0430
+TableColumn.header.SeedingRank.info=\u0417\u043d\u0430\u0447\u0435\u043d\u043d\u044f, \u043d\u0430\u0441\u043a\u0456\u043b\u044c\u043a\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0443 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0456 \u0441\u0456\u0434\u0435\u0440\u0438. \u0427\u0438\u043c \u0432\u0438\u0449\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f, \u0442\u0438\u043c \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0456\u0448\u0435.
+TableColumn.header.shareRatio.info=\u0421\u043a\u0456\u043b\u044c\u043a\u0438 \u0432\u0438 \u0440\u043e\u0437\u0434\u0430\u043b\u0438 \u0432 \u043f\u043e\u0440\u0456\u0432\u043d\u044f\u043d\u043d\u0456 \u0437 \u0442\u0438\u043c, \u0441\u043a\u0456\u043b\u044c\u043a\u0438 \u0432\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u043b\u0438.
+TableColumn.header.size.info=\u0420\u043e\u0437\u043c\u0456\u0440 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457 \u0442\u043e\u0440\u0435\u043d\u0442\u0430 \u043d\u0430 \u0434\u0438\u0441\u043a\u0443
+TableColumn.header.azsubs.ui.column.subs.info=\u041a\u043d\u043e\u043f\u043a\u0430, \u044f\u043a\u0430 \u0434\u043e\u0437\u0432\u043e\u043b\u044f\u0454 \u043f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0438\u0442\u0438 \u0440\u043e\u0437\u0441\u0438\u043b\u043a\u0438, \u044f\u043a\u0456 \u043c\u0456\u0441\u0442\u044f\u0442\u044c \u043f\u043e\u0432'\u044f\u0437\u0430\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438
+TableColumn.header.upspeed.info=\u041f\u043e\u0442\u043e\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0440\u043e\u0437\u0434\u0430\u0447\u0456
+TableColumn.header.downspeed.info=\u041f\u043e\u0442\u043e\u0447\u043d\u0430 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f 
+TableColumn.header.up.info=\u041f\u043e\u0442\u043e\u0447\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0434\u0430\u043d\u0438\u0445, \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0445 \u0456\u043d\u0448\u0438\u043c \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430\u043c
+TableColumn.header.down.info=\u041f\u043e\u0442\u043e\u0447\u043d\u0430 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0434\u0430\u043d\u0438\u0445, \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u0438\u0445 \u0432\u0456\u0434 \u0456\u043d\u0448\u0438\u0445 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0456\u0432
+TableColumn.header.videoLength.info=\u0422\u0440\u0438\u0432\u0430\u043b\u0456\u0441\u0442\u044c \u0432\u043c\u0456\u0441\u0442\u0443
+TableColumn.header.ProgressETA.info=\u041f\u043e\u0454\u0434\u043d\u0443\u0454 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e \u043f\u0440\u043e \u0441\u0442\u0430\u043d, \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f, \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u043d\u0438\u0439 \u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u0438\u0439 \u0447\u0430\u0441 \u0456 \u0448\u0432\u0438\u0434\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0432 \u043e\u0434\u043d\u043e\u043c\u0443 \u0431\u0430\u0433\u0430\u0442\u043e\u0440\u044f\u0434\u043a\u043e\u0432\u043e\u043c\u0443 \u0441\u0442\u043e\u0432\u043f\u0446\u0456.
+TableColumn.header.eta.info=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u043d\u0438\u0439 \u0447\u0430\u0441 \u0434\u043e \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
+Pieces.column.#.info=\u041d\u043e\u043c\u0435\u0440 \u0447\u0430\u0441\u0442\u0438\u043d\u0438
+Peers.column.%.info=\u0412\u0456\u0434\u0441\u043e\u0442\u043e\u043a \u0442\u043e\u0440\u0435\u043d\u0442\u0443, \u044f\u043a\u0438\u0439 \u043f\u043e\u043a\u0438 \u0449\u043e \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0432 \u0443\u0447\u0430\u0441\u043d\u0438\u043a
+TableColumn.header.download.info=\u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0434\u0430\u043d\u0438\u0445, \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u0438\u0445 \u0432\u0456\u0434 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
+TableColumn.header.upload.info=\u041a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0434\u0430\u043d\u0438\u0445, \u0432\u0456\u0434\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0445 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0443
+TableColumn.header.downloadspeed.info=\u0427\u0430\u0441\u0442\u043e\u0442\u0430, \u0437 \u044f\u043a\u043e\u044e \u043c\u0438 \u043e\u0442\u0440\u0438\u043c\u0443\u0454\u043c\u043e \u0434\u0430\u043d\u0456 \u0432\u0456\u0434 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
+TableColumn.header.uploadspeed.info=\u0427\u0430\u0441\u0442\u043e\u0442\u0430, \u0437 \u044f\u043a\u043e\u044e \u0432\u0456\u0434\u043f\u0440\u0430\u043b\u044f\u044e\u0442\u044c\u0441\u044f \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0443 \u0434\u0430\u043d\u0456
+TableColumn.header.lan.info=\u041f\u043e\u0437\u043d\u0430\u0447\u043a\u0430, \u044f\u043a\u0430 \u0432\u043a\u0430\u0437\u0443\u0454, \u0449\u043e \u0443\u0447\u0430\u0441\u043d\u0438\u043a \u0437\u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0412\u0430\u0448\u0456\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0456\u0439 \u043c\u0435\u0440\u0435\u0436\u0456
+TableColumn.header.downloadspeedoverall.info=\u0421\u0435\u0440\u0435\u0434\u043d\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u0430 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0432\u0456\u0434 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430
+Peers.column.pieces.info=\u0413\u0440\u0430\u0444\u0456\u0447\u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u044c, \u044f\u043a\u0430 \u043f\u043e\u043a\u0430\u0437\u0443\u0454, \u044f\u043a\u0456 \u0447\u0430\u0441\u0442\u0438\u043d\u0438 \u0443\u0447\u0430\u0441\u043d\u0438\u043a\u0430 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456
+TableColumn.header.TableColumnNameInfo=\u0406\u043c'\u044f \u0441\u0442\u043e\u0432\u043f\u0446\u044f \u0456 \u043e\u043f\u0438\u0441
+TableColumn.header.TableColumnSample=\u0417\u0440\u0430\u0437\u043e\u043a
+TableColumn.header.TableColumnInfo=\u041e\u043f\u0438\u0441 \u0441\u0442\u043e\u0432\u043f\u0446\u044f
+TableColumn.header.TableColumnChosenColumn=\u0412\u0438\u0431\u0440\u0430\u043d\u0438\u0439 \u0441\u0442\u043e\u0432\u043f\u0435\u0446\u044c
+subs.prop.is_auto_ok=\u0414\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
+label.learnmore=\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u0438 \u0431\u0456\u043b\u044c\u0448\u0435
+ColumnSetup.title=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0441\u0442\u043e\u0432\u043f\u0446\u0456\u0432 \u0434\u043b\u044f '%1'
+ColumnSetup.explain=\u041f\u043e\u0434\u0438\u0432\u0456\u0442\u044c\u0441\u044f \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u043b\u0456\u0432\u043e\u0440\u0443\u0447 \u0456 \u0434\u043e\u0434\u0430\u0439\u0442\u0435 \u0457\u0445 \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0438\u0434\u0438\u043c\u0438\u0445 \u043a\u043e\u043b\u043e\u043d\u043e\u043a \u043f\u0440\u0430\u0432\u043e\u0440\u0443\u0447. \u0420\u043e\u0437\u0448\u0438\u0440\u0442\u0435 \u0430\u0431\u043e \u0437\u043c\u0435\u043d\u0448\u0456\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043e\u043b\u043e\u043d\u043e\u043a \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u0444\u0456\u043b\u044c\u0442\u0440\u0443 \u0432 \u043b\u0456\u0432\u043e\u043c\u0443 \u043d\u0438\u0436\u043d\u044c\u043e\u043c\u0443 \u043a\u0443\u0442\u043a\u0443. \u0422\u0430\u043a\u043e\u0436 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u044e\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u0442\u044f\u0433\u0443\u0432\u0430\u043d\u043d\u044f \u0456 \u043a\u043e\u043c\u0431\u0456\u043d\u0430\u0446\u0456\u0457 \u043a\u043b\u0430\u0432\u0456\u0448.
+ColumnSetup.chosencolumns=\u0412\u0438\u0431\u0440\u0430\u043d\u0456 \u0441\u0442\u043e\u0432\u043f\u0446\u0456
+ColumnSetup.proficiency=\u041c\u0430\u0439\u0441\u0442\u0435\u0440\u043d\u0456\u0441\u0442\u044c:
+ColumnSetup.categories=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457:
+ColumnSetup.filters=\u0424\u0456\u043b\u044c\u0442\u0440\u0438
+ColumnSetup.availcolumns=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0456 %1 \u0441\u0442\u043e\u0432\u043f\u0446\u0456
+ColumnSetup.availcolumns.filteredby=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0456 %1 \u0441\u0442\u043e\u0432\u043f\u0446\u0456, \u044f\u043a\u0456 \u0444\u0456\u043b\u044c\u0442\u0440\u0443\u044e\u0442\u044c\u0441\u044f \u0437\u0430 %2
+devices.view.title=\u041d\u043e\u0441\u0456\u0457
+device.renderer.view.title=\u041e\u0431\u0440\u043e\u0431\u043a\u0430
+device.mediaserver.view.title=\u041c\u0435\u0434\u0456\u0430-\u0441\u0435\u0440\u0432\u0435\u0440\u0438
+device.router.view.title=\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0438
+device.model.desc=\u041e\u043f\u0438\u0441 \u043c\u043e\u0434\u0435\u043b\u0456
+device.model.name=\u041d\u0430\u0437\u0432\u0430 \u043c\u043e\u0434\u0435\u043b\u0456
+device.model.num=\u041d\u043e\u043c\u0435\u0440 \u043c\u043e\u0434\u0435\u043b\u0456
+device.manu.desc=\u0412\u0438\u0440\u043e\u0431\u043d\u0438\u043a
+device.router.is_mapping=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u043f\u0435\u0440\u0435\u0430\u0434\u0440\u0435\u0441\u0430\u0446\u0456\u044f
+device.router.req_map=\u041f\u043e\u0442\u0440\u0456\u0431\u043d\u0430 \u043f\u0435\u0440\u0435\u0430\u0434\u0440\u0435\u0441\u0430\u0446\u0456\u044f
+device.router.configure=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f Upnp
+device.mediaserver.configure=\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u0442\u0438 \u043c\u0456\u0439 \u043c\u0435\u0434\u0456\u0430-\u0441\u0435\u0440\u0432\u0435\u0440
+device.hide=C\u0445\u043e\u0432\u0430\u0442\u0438 \u043d\u043e\u0441\u0456\u0439
+device.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u043f\u0440\u0438\u0445\u043e\u0432\u0430\u043d\u0456 \u043d\u043e\u0441\u0456\u0457
+device.search=\u041f\u043e\u0448\u0443\u043a \u043d\u043e\u0441\u0456\u0457\u0432
+device.router.con_type=\u0417\u0432'\u044f\u0437\u043e\u043a: %1
+device.browse=\u041f\u0435\u0440\u0435\u0433\u043b\u044f\u0434
+device.upnp.desc_url=\u041e\u043f\u0438\u0441 \u043d\u043e\u0441\u0456\u044f
+device.upnp.present_url=\u0410\u0434\u043c\u0456\u043d\u0456\u0441\u0442\u0440\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u043e\u0441\u0456\u044f
+ConfigView.label.maxStalledSeeding=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c '\u0437\u0430\u0441\u0442\u0440\u044f\u0433\u043b\u0438\u0445' [0:\u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0438\u0439]
+device.search.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0438\u0439 \u043f\u043e\u0448\u0443\u043a \u043d\u043e\u0441\u0456\u0457\u0432
+devices.sidebar.simple=\u041f\u0440\u043e\u0441\u0442\u0438\u0439 \u0432\u0438\u0433\u043b\u044f\u0434
+devices.xcode.working_dir=\u0417\u043c\u0456\u043d\u0438\u0442\u0438 \u0434\u0456\u043b\u044f\u043d\u043a\u0443
+devices.xcode.prof_def=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0439 \u043f\u0440\u043e\u0444\u0456\u043b\u044c \u0437\u043c\u0456\u043d\u0438
+devices.xcode.profs=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0456 \u043f\u0440\u043e\u0444\u0456\u043b\u0456 \u0437\u043c\u0456\u043d\u0438
+device.lastseen=\u041e\u0441\u0442\u0430\u043d\u043d\u0456 \u0432\u0456\u0434\u0432\u0456\u0434\u0438\u043d\u0438
+devices.contextmenu.xcode=\u0417\u043c\u0456\u043d\u0438\u0442\u0438 \u0434\u043b\u044f \u043d\u043e\u0441\u0456\u044f
+devices.device=\u041d\u043e\u0441\u0456\u0439
+devices.profile=\u041f\u0440\u043e\u0444\u0456\u043b\u044c
+General.percent=\u0412\u0456\u0434\u0441\u043e\u0442\u043a\u0456\u0432
+devices.installed=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439
+devices.comp.missing=\u041d\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u0432\u0430\u043d\u0430 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0430 Vuze
+devices.state=\u0421\u0442\u0430\u043d
+MainWindow.menu.help.donate=&\u0417\u0440\u043e\u0431\u0438\u0442\u0438 \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u0443
+DonationWindow.noload.title=\u041f\u043e\u0436\u0435\u0440\u0442\u0432\u0430
+DonationWindow.noload.text=\u041d\u0435 \u0432\u0434\u0430\u0454\u0442\u044c\u0441\u044f \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0432\u0456\u043a\u043d\u043e \u043f\u043e\u0436\u0435\u0440\u0442\u0432. \u0421\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0437\u043d\u043e\u0432\u0443 \u043f\u0456\u0437\u043d\u0456\u0448\u0435.
+devices.xcode.only.show=\u041b\u0438\u0448\u0435 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0437\u043c\u0456\u043d\u0435\u043d\u0456 \u0444\u0430\u0439\u043b\u0438 \u043d\u0430 \u043d\u043e\u0441\u0456\u044e
+device.quit.transcoding.title=\u0417\u043c\u0456\u043d\u0430 \u0442\u0440\u0438\u0432\u0430\u0454
+device.quit.transcoding.text=\u0412 \u0446\u0435\u0439 \u0447\u0430\u0441 '%1' \u0437\u043c\u0456\u043d\u044e\u0454\u0442\u044c\u0441\u044f \u0434\u043b\u044f '%2', \u0437\u043c\u0456\u043d\u0435\u043d\u043e %3%.\n\u042f\u043a\u0449\u043e \u0412\u0438 \u0432\u0438\u0439\u0434\u0435\u0442\u0435 \u0437\u0430\u0440\u0430\u0437, \u043f\u0440\u0438 \u043d\u0430\u0441\u0442\u0443\u043f\u043d\u043e\u043c\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0443 \u0432\u0441\u044e \u0434\u0456\u044e \u0434\u043e\u0432\u0435\u0434\u0435\u0442\u044c\u0441\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0438 \u0441\u043f\u043e\u0447\u0430\u0442\u043a\u0443.
+download.removerules.unauthorised.data=\t\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0434\u0430\u043d\u0456
+device.config.xcode.maxbps=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430 \u0447\u0430\u0441\u0442\u043e\u0442\u0430 \u0437\u043c\u0456\u043d\u0438, \u041a\u0431/\u0441 [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u0430]
+device.xcode=\u0417\u043c\u0456\u043d\u0438\u0442\u0438
+device.xcode.always=\u0417\u0430\u0432\u0436\u0434\u0438
+device.xcode.whenreq=\u041a\u043e\u043b\u0438 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e
+device.xcode.never=\u041d\u0456\u043a\u043e\u043b\u0438
+devices.copy.pending=\u041e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u043a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043d\u044f \u0444\u0430\u0439\u043b\u0443
+devices.sidebar.hide.rend.generic=\u041f\u0440\u0438\u0445\u043e\u0432\u0430\u0442\u0438 \u0437\u0430\u0433\u0430\u043b\u044c\u043d\u0456 \u043d\u043e\u0441\u0456\u0457
+v3.devicesview.infobar.text2=\u0414\u043b\u044f \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0442\u044f\u0433\u043d\u0456\u0442\u044c \u0432\u043c\u0456\u0441\u0442 \u0412\u0430\u0448\u043e\u0457 \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0438 \u0434\u043e \u043d\u043e\u0441\u0456\u0457\u0432 \u043d\u0430 \u0411\u043e\u043a\u043e\u0432\u0456\u0439 \u043f\u0430\u043d\u0435\u043b\u0456.  \u0429\u043e\u0431 \u043f\u043e\u0431\u0430\u0447\u0438\u0442\u0438, \u0447\u0438 \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u043e\u0432\u0443\u0432\u0430\u043d\u043d\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0438\u043b\u043e\u0441\u044f, \u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u043d\u043e\u0441\u0456\u0439 \u0441\u043f\u0440\u0430\u0432\u0430.
+iconBar.transcode=\u041d\u043e\u0441\u0456\u0439
+iconBar.transcode.tooltip=\u0417\u0440\u043e\u0431\u0438\u0442\u0438 \u0434\u0430\u043d\u0456 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u043c\u0438 \u0434\u043b\u044f \u043d\u043e\u0441\u0456\u044f
+device.retry.copy=\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0438 \u043a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043d\u044f
+devices.copy.fail=\u041d\u0435\u0432\u0434\u0430\u043b\u0435 \u043a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043d\u044f \u043d\u0430 \u043d\u043e\u0441\u0456\u0439
+devices.on.demand=\u0417\u0430 \u0437\u0430\u043f\u0438\u0442\u043e\u043c
+devices.ready=\u0413\u043e\u0442\u043e\u0432\u0438\u0439
+TableColumn.header.trancode_qpos.info=\u041f\u043e\u0437\u0438\u0446\u0456\u044f \u0432 \u0447\u0435\u0440\u0437\u0456 \u0437\u043c\u0456\u043d\u0438
+TableColumn.header.profile=\u041d\u043e\u0441\u0456\u0439
+TableColumn.header.profile.info=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0444\u0456\u043b\u044c \u0437\u043c\u0456\u043d\u0438
+TableColumn.header.copied=\u041a\u043e\u043f\u0456\u044e\u0454\u0442\u044c\u0441\u044f
+TableColumn.header.device=\u041d\u043e\u0441\u0456\u0439
+TableColumn.header.device.info=\u0426\u0456\u043b\u044c\u043e\u0432\u0438\u0439 \u043d\u043e\u0441\u0456\u0439
+TableColumn.header.trancode_completion=\u0412\u0456\u0434\u0441\u043e\u0442\u043e\u043a \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0443\u0432\u0430\u043d\u043d\u044f
+# This is the beginning of the word "View".  It's right aligned under the icon bar item
+v3.iconBar.view.big=\u0412\u0438\u0433
+v3.iconBar.view.big.tooltip=\u041f\u0440\u043e\u0441\u0442\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a
+# This is the end of the word "View".  It's left aligned under the icon bar item
+v3.iconBar.view.small=\u043b\u044f\u0434
+v3.iconBar.view.small.tooltip=\u0420\u043e\u0437\u0448\u0438\u0440\u0435\u043d\u043d\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a
+general.dont.ask.again=\u0411\u0456\u043b\u044c\u0448\u0435 \u043d\u0435 \u0437\u0430\u043f\u0438\u0442\u0443\u0432\u0430\u0442\u0438
+v3.menu.device.exploreTranscodes=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438
+v3.menu.device.exploreTranscodes._windows=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 \u0432 \u041f\u0440\u043e\u0432\u0456\u0434\u043d\u0438\u043a\u0443
+v3.menu.device.exploreTranscodes._mac=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 \u0432 \u043f\u043e\u043b\u0456 \u041f\u043e\u0448\u0443\u043a\u0443
+v3.menu.device.defaultprofile=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0439 \u043f\u0440\u043e\u0444\u0456\u043b\u044c
+devices.button.installitunes=\u0412\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 \u043e\u0431'\u0454\u0434\u043d\u0430\u043d\u043d\u044f \u0437 iTunes
+device.itunes.install=\u0412\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0438 iTunes
+device.itunes.start=\u0412\u0430\u043c \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 iTunes \u0430\u0431\u043e \u0432\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a
+device.itunes.install_problem=\u0404 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438 \u0437 \u043e\u0431'\u0454\u0434\u043d\u0430\u043d\u043d\u044f\u043c \u0437 iTunes
+devices.downloading=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
+TableColumn.header.duration=\u0422\u0440\u0438\u0432\u0430\u043b\u0456\u0441\u0442\u044c
+TableColumn.header.resolution=\u0420\u043e\u0437\u0434\u0456\u043b\u044c\u043d\u0430 \u0437\u0434\u0430\u0442\u043d\u0456\u0441\u0442\u044c
+devices.xcode.autoStart=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u0438 \u043f\u0440 \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e\u0441\u0442\u0456
+option.askeverytime=\u0417\u0430\u043f\u0438\u0442\u0443\u0432\u0430\u0442\u0438 \u0449\u043e\u0440\u0430\u0437\u0443
+option.rememberthis=\u0417\u0430\u043f\u0430\u043c'\u044f\u0442\u0430\u0442\u0438 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f
+devices.associate=\u0417\u0432'\u044f\u0437\u0430\u0442\u0438 \u0437
+devices.associate.already=\u0412\u0436\u0435 \u0437\u0432'\u044f\u0437\u0430\u043d\u043e
+devices.always.cache=\u0417\u0430\u043f\u0430\u043c'\u044f\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043d\u0435\u0437\u043c\u0456\u043d\u0435\u043d\u0456 \u0444\u0430\u0439\u043b\u0438
+devices.turnon.prepageload=\u0429\u043e\u0431 \u0432\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0446\u044e \u043c\u043e\u0436\u043b\u0438\u0432\u0456\u0441\u0442\u044c, \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0435 \u0432\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0434\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0456\u0432.
+devices.turnon.itunes=\u0412\u0440\u0430\u0445\u043e\u0432\u0443\u044e\u0447\u0438 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0443 iTunes (\u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u0430 \u0434\u043b\u044f \u043d\u043e\u0441\u0456\u0457\u0432 Apple)
+devices.turnon.qos=\u0420\u043e\u0437\u0434\u0430\u0442\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0447\u0435\u0440\u0435\u0437 Vuze
+devices.turnon.title=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u043a\u0443 \u043d\u043e\u0441\u0456\u0457\u0432
+devices.choose.device.title=\u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u043f\u0440\u0438\u0441\u0442\u0440\u0456\u0439, \u043d\u0430 \u044f\u043a\u043e\u043c\u0443 \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u044e\u0432\u0430\u0442\u0438\u043c\u0435\u0442\u044c\u0441\u044f \u0446\u0435 \u0432\u0456\u0434\u0435\u043e:
+devices.choose.profile.info.text=\u041f\u0456\u0441\u043b\u044f \u0432\u0430\u0448\u043e\u0433\u043e \u0432\u0438\u0431\u043e\u0440\u0443, Vuze \u0432\u0438\u044f\u0432\u0438\u0442\u044c, \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454\u0442\u044c\u0441\u044f \u0447\u0438 \u043d\u0456 \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f \u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u0432\u0456\u0434\u0435\u043e\u0444\u043e\u0440\u043c\u0430\u0442\u0443 \u043d\u0430 \u0432\u0430\u0448\u043e\u043c\u0443 \u043d\u043e\u0441\u0456\u044e, \u0456 \u0441\u0442\u0432\u043e\u0440\u0438\u0442\u044c \u0441\u0443\u043c\u0456\u0441\u043d\u0443 \u0434\u043b\u044f \u043d\u043e\u0441\u0456\u044f \u043a\u043e\u043f\u0456\u044e, \u044f\u043a\u0449\u043e \u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e.\n\n\u041f\u0440\u043e\u0432\u0435\u0434\u0456\u0442\u044c \u043c\u0438\u0448\u0435\u044e \u043d\u0430\u0434 \u0432\u0438\u0431\u0440\u0430\u043d\u0438\u043c \u043d\u043e\u0441\u0456\u0454\u043c \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u0434\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c.
+devices.choose.profile.info.title.selected=\u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 %1:
+devices.view.heading=\u041f\u0435\u0440\u0435\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f \u0434\u0430\u043d\u0438\u0445 \u0434\u043b\u044f \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f \u043d\u0430 \u043d\u043e\u0441\u0456\u044e
+device.view.heading=\u0414\u0430\u043d\u0456 \u0434\u043b\u044f %1
+devices.choose.device.info.title=\u041f\u0456\u0434\u043a\u0430\u0437\u043a\u0430 \u043d\u043e\u0441\u0456\u044f
+devices.choose.device.info.text=\u041d\u0430\u0441\u0442\u0443\u043f\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0443, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0442\u044f\u0433\u043d\u0456\u0442\u044c \u0444\u0430\u0439\u043b\u0438 \u0434\u043e\u043d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e\u0433\u043e \u043d\u043e\u0441\u0456\u044f \u043d\u0430 \u0411\u043e\u043a\u043e\u0432\u0456\u0439 \u043f\u0430\u043d\u0435\u043b\u0456.
+label.clickone=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u0440\u0430\u0437
+Button.turnon=\u0412\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438
+ConfigView.label.dm.dblclick=\u0414\u0432\u0456\u0447\u0456 \u043a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043f\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0443:
+ConfigView.option.dm.dblclick.play=\u0412\u0456\u0434\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0432\u043c\u0456\u0441\u0442
+ConfigView.option.dm.dblclick.details=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u041f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0443
+ConfigView.option.dm.dblclick.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0444\u0430\u0439\u043b
+ConfigView.option.dm.dblclick.show._mac=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0444\u0430\u0439\u043b(\u0438) \u0432 \u0432\u0456\u043a\u043d\u0456 \u041f\u043e\u0448\u0443\u043a\u0443
+ConfigView.option.dm.dblclick.show._windows=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0444\u0430\u0439\u043b(\u0438) \u0432 \u041f\u0440\u043e\u0432\u0456\u0434\u043d\u0438\u043a\u0443
+subscriptions.column.auto-download=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
+xcode.deletedata.title=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0437\u043c\u0456\u043d\u0435\u043d\u0438\u0439 \u0432\u043c\u0456\u0441\u0442
+xcode.deletedata.message=\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u043d\u0435\u0433\u0430\u0439\u043d\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u043a\u043e\u043f\u0456\u044e  '%1', \u0437\u043c\u0456\u043d\u0435\u043d\u0443 \u0434\u043b\u044f '%2'%3?
+xcode.deletedata.message.2=\n(\u043a\u043e\u043f\u0456\u044f \u043c\u043e\u0436\u0435 \u0434\u043e\u0441\u0456 \u0456\u0441\u043d\u0443\u0432\u0430\u0442\u0438 \u0432 '%1')
+v3.deviceview.infobar.line1=\u041f\u0435\u0440\u0435\u0442\u044f\u0433\u043d\u0456\u0442\u044c \u0432\u0456\u0434\u0435\u043e \u0437 \u0412\u0430\u0448\u043e\u0457 \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u043a\u0438 \u0434\u043e \u0431\u0430\u0436\u0430\u043d\u043e\u0433\u043e \u043d\u043e\u0441\u0456\u044f.
+v3.deviceview.infobar.line2=\u0412\u0456\u0434\u0442\u0432\u043e\u0440\u044e\u0439\u0442\u0435 \u0412\u0430\u0448\u0435 \u0432\u0456\u0434\u0435\u043e \u0431\u0443\u0434\u044c-\u0434\u0435 - \u043d\u0430 iPhone, iPod, TV
+v3.deviceview.infobar.line1.generic=\u041f\u0435\u0440\u0435\u0442\u044f\u0433\u043d\u0456\u0442\u044c \u0432\u0456\u0434\u0435\u043e \u0437 \u0412\u0430\u0448\u043e\u0457 \u0431\u0456\u0431\u043b\u0456\u043e\u0442\u043a\u0438 \u0434\u043e %1 \u043d\u0430 \u0412\u0430\u0448\u0456\u0439 \u0411\u043e\u043a\u043e\u0432\u0456\u0439 \u043f\u0430\u043d\u0435\u043b\u0456.
+v3.deviceview.infobar.line2.itunes=\u0412\u0456\u0434\u0435\u043e \u0437'\u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u0446\u0456 iTunes Movies, \u043a\u043e\u043b\u0438 \u0431\u0443\u0434\u0443\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u0438\u043c\u0438 \u0434\u043e \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f.
+v3.deviceview.infobar.line2.xbox=\u041f\u043e\u0442\u043e\u043a\u043e\u0432\u0435 \u0432\u0456\u0434\u0435\u043e \u0434\u043b\u044f \u0412\u0430\u0448\u043e\u0433\u043e Xbox 360 \u0432\u0438\u0431\u0438\u0440\u0430\u0454\u0442\u044c\u0441\u044f: My XBox -> Video Library -> Vuze.
+v3.deviceview.infobar.line2.ps3=\u041f\u043e\u0442\u043e\u043a\u043e\u0432\u0435 \u0432\u0456\u0434\u0435\u043e \u0434\u043b\u044f \u0412\u0430\u0448\u043e\u0433\u043e PS3 \u0432\u0438\u0431\u0438\u0440\u0430\u0454\u0442\u044c\u0441\u044f: Videos -> Vuze.
+devices.copy_url=\u041a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u0443 \u0430\u0434\u0440\u0435\u0441\u0443 \u0434\u043e \u0411\u0443\u0444\u0435\u0440\u0443 \u043e\u0431\u043c\u0456\u043d\u0443
+devices.converting=\u041f\u0435\u0440\u0435\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f
+Button.reload=\u041f\u0435\u0440\u0435\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438
+devices.auto.start=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a
+Subscription.menu.setcookies=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043a\u0443\u043a\u0456\u0441\u0438
+general.enter.cookies=\u041a\u0443\u043a\u0456\u0441\u0438 \u0432\u0445\u043e\u0434\u0443
+device.config.xcode.workdir=\u0422\u0435\u043a\u0430 \u0434\u043b\u044f \u0437\u043c\u0456\u043d\u0435\u043d\u0438\u0445 \u0444\u0430\u0439\u043b\u0456\u0432
+MyTorrentsView.menu.clear_alloc_data=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0438 \u0440\u043e\u0437\u043c\u0456\u0449\u0435\u043d\u043d\u044f
+DiskManager.error.nospace=\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043d\u044c\u043e \u0434\u0438\u0441\u043a\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u0443
+ConfigView.section.file.rename.incomplete=\u0414\u043e\u0434\u0430\u0432\u0430\u0442\u0438 \u0441\u0443\u0444\u0456\u043a\u0441 \u0434\u043e \u043d\u0435\u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0438\u0445 \u0444\u0430\u0439\u043b\u0456\u0432
+subscriptions.config.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0435 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
+subscriptions.config.autostartdls=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u043e\u0447\u0438\u043d\u0430\u0442\u0438 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u043f\u0440\u0438 \u0434\u043e\u0434\u0430\u0432\u0430\u043d\u043d\u0456
+subscriptions.config.autostart.min=\u041f\u043e\u0447\u0438\u043d\u0430\u0442\u0438, \u044f\u043a\u0449\u043e >= MB [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043e]
+subscriptions.config.autostart.max=\u041f\u043e\u0447\u0438\u043d\u0430\u0442\u0438, \u044f\u043a\u0449\u043e <= MB [0: \u043d\u0435\u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043e]
+dlg.corewait.title=\u0406\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u044f \u044f\u0434\u0440\u0430
+dlg.corewait.text=\u0417\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435, \u0431\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430...\n\n\u0412\u0430\u0448 \u0437\u0430\u043f\u0438\u0442 \u0431\u0443\u0434\u0435 \u043e\u0431\u0440\u043e\u0431\u043b\u0435\u043d\u0438\u043c \u043f\u0456\u0441\u043b\u044f \u0442\u043e\u0433\u043e, \u044f\u043a Vuze \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0456\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u044e
+library.core.wait=\u0417\u0430\u0447\u0435\u043a\u0430\u0439\u0442\u0435, \u0431\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430...\n\u0406\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u044f \u043a\u043b\u0456\u0454\u043d\u0442\u0430 Vuze
+ConfigView.label.StartUIBeforeCore=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u0433\u0440\u0430\u0444\u0456\u043a\u0443 \u043f\u0435\u0440\u0435\u0434 \u0456\u043d\u0456\u0446\u0456\u0430\u043b\u0456\u0437\u0430\u0446\u0456\u0454\u044e \u044f\u0434\u0440\u0430
+general.add.friends=\u0414\u043e\u0434\u0430\u0439\u0442\u0435 \u0434\u0440\u0443\u0437\u0456\u0432!
+general.all.friends=\u0412\u0441\u0456 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0456
+friend.mod.subs=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043f\u0440\u0430\u0432\u043e\u044e \u043a\u043d\u043e\u043f\u043a\u043e\u044e \u0434\u043b\u044f \u0437\u043c\u0456\u043d\u0438 \u043f\u0456\u0434\u043f\u0438\u0441\u043e\u043a
+TableColumn.header.class=\u041a\u043b\u0430\u0441
+device.rss.group=\u041c\u0456\u0441\u0446\u0435\u0432\u0430 \u0441\u0442\u0440\u0456\u0447\u043a\u0430 RSS
+devices.xcode.rsspub=\u041f\u0443\u0431\u043b\u0456\u043a\u0443\u0432\u0430\u0442\u0438 \u0441\u0442\u0440\u0456\u0447\u043a\u0443 RSS
+device.rss.enable=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0441\u0442\u0440\u0456\u0447\u043a\u0443 RSS \u0437 \u0437\u043c\u0456\u043d\u0435\u043d\u043e\u0433\u043e \u0432\u043c\u0456\u0441\u0442\u0443 - \u0446\u0435 \u0437\u0440\u043e\u0431\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0438\u043c \u0432\u043c\u0456\u0441\u0442 \u0434\u043b\u044f \u0447\u0438\u0442\u0430\u0447\u0456\u0432 \u0441\u0442\u0440\u0456\u0447\u043e\u043a RSS
+device.rss.port=\u041f\u043e\u0440\u0442 \u0441\u0442\u0440\u0456\u0447\u043a\u0438 RSS
+device.rss.view=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u043d\u0443\u0442\u0438 \u0441\u0442\u0440\u0456\u0447\u043a\u0443 RSS
+device.rss.localonly=\u041e\u0431\u043c\u0435\u0436\u0438\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043b\u0438\u0448\u0435 \u0434\u043e \u0446\u044c\u043e\u0433\u043e \u043a\u043e\u043c\u043f'\u044e\u0442\u0435\u0440\u0430
+rcm.rc_tracker.tt=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u043f\u0435\u0440\u0435\u0433\u043b\u044f\u043d\u0443\u0442\u0438 \u0442\u0440\u0435\u043a\u0435\u0440
+rcm.rc_hash.tt=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0446\u0435\u0439 \u0432\u043c\u0456\u0441\u0442
+rcm.rc_title.tt=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c, \u0449\u043e\u0431 \u0437\u043d\u0430\u0439\u0442\u0438 \u0446\u0435\u0439 \u0432\u043c\u0456\u0441\u0442
+devices.xcode.autoCopy=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0434\u043e \u0442\u0435\u043a\u0438
+devices.xcode.setcopyto=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u043a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043d\u044f \u0434\u043e \u0442\u0435\u043a\u0438...
+devices.xcode.setcopyto.title=\u0412\u043a\u0430\u0436\u0456\u0442\u044c \u043a\u0456\u043d\u0446\u0435\u0432\u0443 \u0442\u0435\u043a\u0443
+devices.copy.folder.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 \u0432 \u0442\u0435\u043a\u0443
+devices.copy.folder.dest=\u041a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0432 \u0442\u0435\u043a\u0443
+TableColumn.menu.maxuploads=\u041a-\u0441\u0442\u044c \u043c\u0430\u043a\u0441. \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c
+devices.xcode.mancopy=\u0412\u0440\u0443\u0447\u043d\u0443 \u043a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438
+devices.xcode.show.cat=\u0420\u043e\u0437\u043f\u043e\u0434\u0456\u043b\u0438\u0442\u0438 \u043f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u044f\u043c
+ConfigView.label.alwaysShowLibraryHeader=\u0417\u0430\u0432\u0436\u0434\u0438 \u043f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0432 \u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u0446\u0456 (\u041c\u043e\u0457 \u0442\u043e\u0440\u0435\u043d\u0442\u0438)
+devices.cat.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0456\u0457
+devices.tivo.machine=TiVo
+devices.info.copypending=\u041e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u043a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043d\u044f %1 \u0444\u0430\u0439\u043b\u0430(\u0456\u0432)
+device.error.xcodefail=\u041d\u0435\u0432\u0434\u0430\u043b\u0430 \u0437\u043c\u0456\u043d\u0430
+device.error.copyfail=\u041e\u0434\u0438\u043d \u0430\u0431\u043e \u043a\u0456\u043b\u044c\u043a\u0430 \u0444\u0430\u0439\u043b\u0456\u0432 \u043d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u043e \u0441\u043a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0434\u043e \u0442\u0435\u043a\u0438
+device.error.copytonotset='\u041a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043d\u044f \u0434\u043e \u0442\u0435\u043a\u0438' "%1", \u044f\u043a\u0430 \u043d\u0435 \u0432\u043a\u0430\u0430\u0437\u043d\u0430
+device.error.copytomissing='\u041a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043d\u044f \u0434\u043e \u0442\u0435\u043a\u0438' "%1", \u044f\u043a\u0443 \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e
+device.error.copytonowrite='\u041a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043d\u044f \u0434\u043e \u0442\u0435\u043a\u0438' "%1", \u0432 \u044f\u043a\u0443 \u043d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u0438
+device.error.copyfail2=\u041e\u0434\u0438\u043d \u0430\u0431\u043e \u043a\u0456\u043b\u044c\u043a\u0430 \u0444\u0430\u0439\u043b\u0456\u0432 \u043d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u043e \u0441\u043a\u043e\u043f\u0456\u044e\u0432\u0430\u0442\u0438 \u0434\u043e \u043d\u043e\u0441\u0456\u044f
+v3.deviceview.infobar.line2.tivo=\u041f\u043e\u0442\u043e\u043a\u043e\u0432\u0435 \u0432\u0456\u0434\u0435\u043e \u0434\u043b\u044f \u0412\u0430\u0448\u043e\u0433\u043e TiVo \u0432\u0438\u0431\u0438\u0440\u0430\u0454\u0442\u044c\u0441\u044f \u0432 Vuze \u0432 \u043f\u043e\u0442\u043e\u0447\u043d\u043e\u043c\u0443 \u0441\u043f\u0438\u0441\u043a\u0443 \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044f.
+v3.deviceview.infobar.line2.psp=\u0412\u0456\u0434\u0435\u043e \u0441\u043a\u043e\u043f\u0456\u044e\u0454\u0442\u044c\u0441\u044f \u0434\u043e PSP, \u043a\u043e\u043b\u0438 \u043d\u043e\u0441\u0456\u0439 \u0431\u0443\u0434\u0435 \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u043d\u043e.
+devices.info.copypending2=\u041e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u043d\u044f \u043a\u043e\u043f\u0456\u044e\u0432\u0430\u043d\u043d\u044f %1 \u0444\u0430\u0439\u043b\u0430(\u0456\u0432), \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u0439\u0442\u0435 \u0412\u0430\u0448 \u043d\u043e\u0441\u0456\u0439
+subscriptions.column.nb-subscribers=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0447\u0443\u044e\u0447\u0456
+# The remaining keys were not in MessagesBundle.properties
+=
+MyTorrentsView.menu.rename.displayed_and_save_path.enter.message.2=\u042f\u043a\u0449\u043e \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0432\u043a\u0430\u0437\u0430\u043d\u0438\u0439, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u043c\u0435\u0442\u044c\u0441\u044f \u043e\u0440\u0438\u0433\u0456\u043d\u0430\u043b\u044c\u043d\u0456 \u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044f.
+v3.MainWindow.recentDL=\u041e\u0441\u0442\u0430\u043d\u043d\u0456 %1 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c
+v3.MainWindow.myMedia.noneSelected=\u0412\u0438 \u043c\u0430\u0454\u0442\u0435 %1 \u0447\u0430\u0441\u0442\u0438\u043d \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457.\n%2 \u0437 \u043d\u0438\u0445 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u0456.\n\n\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043f\u043e \u0440\u044f\u0434\u043a\u0443 \u0434\u043b\u044f \u0434\u043e\u0434\u0430\u0442\u043a\u043e\u0432\u043e\u0457 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u0457
+ConfigView.section.style.useNewStyleMessageBox=\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438 \u043d\u043e\u0432\u0438\u0439 \u0441\u0442\u0438\u043b\u044c \u0441\u043a\u0440\u0438\u043d\u044c\u043a\u0438 \u0434\u043b\u044f \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c
+Scrape.status.error.bad??????=\u0417\u0430\u0434\u0430\u043d\u0430 \u0430\u0434\u0440\u0435\u0441\u0430 \u043d\u0435 \u043f\u0456\u0434\u0442\u0440\u0438\u043c\u0443\u0454 \u0441\u043f\u0435\u0446\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u0457 \u0448\u043a\u0440\u044f\u0431\u0430\u043d\u044c.
+MyTorrentsView.menu.rename.save_path.enter.message.2=\u042f\u043a\u0449\u043e \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0432\u043a\u0430\u0437\u0430\u043d\u0438\u0439, \u0432\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0432\u0430\u0442\u0438\u043c\u0435\u0442\u044c\u0441\u044f \u043e\u0440\u0438\u0433\u0456\u043d\u0430\u043b\u044c\u043d\u0435 \u0456\u043c'\u044f.
+MyTorrentsView.menu.rename.displayed.enter.message.2=\u042f\u043a\u0449\u043e \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0432\u043a\u0430\u0437\u0430\u043d\u0438\u0439, \u0434\u0456\u044f\u0442\u0438\u043c\u0435 \u043e\u0440\u0438\u0433\u0456\u043d\u0430\u043b\u044c\u043d\u0435 \u0456\u043c'\u044f.
+v3.HomeReminder.title=\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0434\u043e\u0434\u0430\u043d\u0435
+ConfigView.section.language.Update??????=\u041f\u043e\u043d\u043e\u0432\u0438\u0442\u0438 \u0430\u0434\u0440\u0435\u0441\u0443
+v3.HomeReminder.gohome=\u041f\u0435\u0440\u0435\u043c\u043a\u043d\u0443\u0442\u0438\u0441\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u044e \u043f\u0430\u043d\u0435\u043b\u0456 \u0456\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0456\u0432
+v3.HomeReminder.text='%1' \u0431\u0443\u0432 \u0434\u043e\u0434\u0430\u043d\u0438\u0439 \u0434\u043e \u0432\u0430\u0448\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0443 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u044c.\n\n\u042f\u043a\u0449\u043e \u0431\u0430\u0436\u0430\u0454\u0442\u0435 \u0441\u043f\u043e\u0441\u0442\u0435\u0440\u0456\u0433\u0430\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0435\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f, \u0430\u0431\u043e \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0444\u0430\u0439\u043b \u043f\u0456\u0441\u043b\u044f \u0437\u0430\u043a\u0456\u043d\u0447\u0435\u043d\u043d\u044f, \u043a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u043f\u043e \u041f\u0430\u043d\u0435\u043b\u0456 \u0456\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0456\u0432.
+iconBar.open??????.tooltip=\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0430\u0434\u0440\u0435\u0441\u0443
+Tab.closeHint=(\u041d\u0430\u0442\u0438\u0441\u043d\u0456\u0442\u044c 'Esc' \u0434\u043b\u044f \u0437\u0430\u043a\u0440\u0438\u0442\u0442\u044f)
+v3.MainWindow.recentDL.library=\u0411\u0456\u0431\u043b\u0456\u043e\u0442\u0435\u043a\u0430 >>
diff --git a/org/gudy/azureus2/platform/macosx/NativeInvocationBridge.java b/org/gudy/azureus2/platform/macosx/NativeInvocationBridge.java
index 4d465dd..087cd50 100644
--- a/org/gudy/azureus2/platform/macosx/NativeInvocationBridge.java
+++ b/org/gudy/azureus2/platform/macosx/NativeInvocationBridge.java
@@ -39,28 +39,28 @@ public abstract class NativeInvocationBridge
 
     protected NativeInvocationBridge(){}
 
-    static
-    {
-        try
-        {
-            Object newInstance = Class.forName("org.gudy.azureus2.platform.macosx.access.cocoa.CocoaJavaBridge").getConstructor(null).newInstance(null);
-            instance = (NativeInvocationBridge)newInstance;
-        }
-        catch(Exception e)
-        {
-            Debug.out(e);
-            instance = new DummyBridge();
-        }
-    }
-
-    /**
-     * Gets the singleton
-     * @return The NativeInvocationBridge singleton
-     */
-    protected static final NativeInvocationBridge sharedInstance()
-    {
-        return instance;
-    }
+  /**
+   * Gets the singleton
+   * @return The NativeInvocationBridge singleton
+   */
+	protected static final NativeInvocationBridge sharedInstance() {
+		if (instance == null) {
+			try {
+				Object newInstance = Class.forName(
+						"org.gudy.azureus2.platform.macosx.access.cocoa.CocoaJavaBridge").getConstructor(
+						null).newInstance(null);
+				instance = (NativeInvocationBridge) newInstance;
+			} catch (Throwable e) {
+				Debug.out(e);
+				instance = new DummyBridge();
+			}
+		}
+		return instance;
+	}
+	
+	protected final static boolean hasSharedInstance() {
+		return instance != null;
+	}
 
      /**
      * @see PlatformManager#performRecoverableFileDelete(java.io.File)
diff --git a/org/gudy/azureus2/platform/macosx/PlatformManagerImpl.java b/org/gudy/azureus2/platform/macosx/PlatformManagerImpl.java
index 8721e90..4d0c6a6 100644
--- a/org/gudy/azureus2/platform/macosx/PlatformManagerImpl.java
+++ b/org/gudy/azureus2/platform/macosx/PlatformManagerImpl.java
@@ -506,7 +506,13 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
      */
     public void dispose()
     {
-        NativeInvocationBridge.sharedInstance().dispose();
+    	try {
+    		if (NativeInvocationBridge.hasSharedInstance()) {
+    			NativeInvocationBridge.sharedInstance().dispose();
+    		}
+    	} catch (Throwable t) {
+    		Debug.out("Problem disposing NativeInvocationBridge", t);
+    	}
     }
 
     /**
@@ -577,9 +583,12 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
             StringBuffer sb = new StringBuffer();
             sb.append("tell application \"");
             sb.append(getFileBrowserName());
-            sb.append("\" to reveal (posix file \"");
+            sb.append("\"\n");
+            sb.append("reveal (posix file \"");
             sb.append(path);
-            sb.append("\" as alias)");
+            sb.append("\" as alias)\n");
+            sb.append("activate\n");
+            sb.append("end tell\n");
 
             try
             {
diff --git a/org/gudy/azureus2/platform/macosx/PlatformManagerUpdateChecker.java b/org/gudy/azureus2/platform/macosx/PlatformManagerUpdateChecker.java
index 34f8df2..b3473c7 100644
--- a/org/gudy/azureus2/platform/macosx/PlatformManagerUpdateChecker.java
+++ b/org/gudy/azureus2/platform/macosx/PlatformManagerUpdateChecker.java
@@ -289,7 +289,7 @@ PlatformManagerUpdateChecker
 
 					// skip the directory entry
 
-					if (name.length() > 0) {
+					if ( name.length() > 0 ){
 
 						rd.reportActivity("Adding update action for '" + name + "'");
 
@@ -301,14 +301,19 @@ PlatformManagerUpdateChecker
 						
 						String	resource_name = name.replaceAll( "/", "-" );
 						
-						installer.addResource(resource_name, zip, false);
+						installer.addResource( resource_name, zip, false );
 
+						String target = 
+							installer.getInstallDir() +
+							File.separator + SystemProperties.getApplicationName() + ".app" + 
+							File.separator + name;
+
+						installer.addMoveAction( resource_name, target ); 
 						
-						installer.addMoveAction(
-								resource_name, 
-								installer.getInstallDir() +
-									File.separator + SystemProperties.getApplicationName() + ".app" + 
-									File.separator + name );
+						if ( name.endsWith( ".jnilib" ) || name.endsWith( "JavaApplicationStub" )){
+							
+							installer.addChangeRightsAction( "755", target );
+						}
 					}
 				}
 			}
diff --git a/org/gudy/azureus2/platform/macosx/access/jnilib/OSXAccess.java b/org/gudy/azureus2/platform/macosx/access/jnilib/OSXAccess.java
index 7b0b4a1..32f940e 100644
--- a/org/gudy/azureus2/platform/macosx/access/jnilib/OSXAccess.java
+++ b/org/gudy/azureus2/platform/macosx/access/jnilib/OSXAccess.java
@@ -22,8 +22,6 @@ package org.gudy.azureus2.platform.macosx.access.jnilib;
 import java.io.File;
 import java.util.Map;
 
-import org.eclipse.swt.internal.carbon.AEDesc;
-
 import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.drivedetector.DriveDetectorFactory;
@@ -39,16 +37,39 @@ public class OSXAccess
 {
 	private static boolean bLoaded = false;
 
-	private static boolean DEBUG = Constants.isCVSVersion();
+	private static boolean DEBUG = false;
 
 	static {
+		if (!Constants.isOSX_10_5_OrHigher || !loadLibrary("OSXAccess_10.5")) {
+			loadLibrary("OSXAccess");
+		}
+	}
+
+
+	private static boolean loadLibrary(String lib) {
 		try {
-			System.loadLibrary("OSXAccess");
-			System.out.println("OSXAccess v" + getVersion() + " Load complete!");
+			SystemLoadLibrary(lib);
+			System.out.println(lib + " v" + getVersion() + " Load complete!");
 			bLoaded = true;
 			initDriveDetection();
-		} catch (UnsatisfiedLinkError e1) {
-			Debug.out("Could not find libOSXAccess.jnilib");
+		} catch (Throwable e1) {
+			Debug.out("Could not find lib" + lib + ".jnilib", e1);
+		}
+		
+		return bLoaded;
+	}
+	
+	private static  void SystemLoadLibrary(String lib) throws Throwable {
+		try {
+			System.loadLibrary(lib);
+		} catch (Throwable t) {
+			// if launched from eclipse, updates will put it into ./Azureus.app/Contents/Resources/Java/dll
+			try {
+				File f = new File("Azureus.app/Contents/Resources/Java/dll/lib" + lib + ".jnilib");
+				System.load(f.getAbsolutePath());
+			} catch (Throwable t2) {
+				throw t;
+			}
 		}
 	}
 
@@ -88,7 +109,7 @@ public class OSXAccess
 	}
 
 	public static final native int AEGetParamDesc(int theAppleEvent,
-			int theAEKeyword, int desiredType, AEDesc result);
+			int theAEKeyword, int desiredType, Object result); //AEDesc result
 
 	public static final native String getVersion();
 
diff --git a/org/gudy/azureus2/platform/unix/PlatformManagerUnixPlugin.java b/org/gudy/azureus2/platform/unix/PlatformManagerUnixPlugin.java
index d207e8e..9551f61 100644
--- a/org/gudy/azureus2/platform/unix/PlatformManagerUnixPlugin.java
+++ b/org/gudy/azureus2/platform/unix/PlatformManagerUnixPlugin.java
@@ -36,6 +36,7 @@ import org.gudy.azureus2.update.UpdaterUtils;
 
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 
 import org.gudy.azureus2.plugins.Plugin;
 import org.gudy.azureus2.plugins.PluginException;
@@ -233,11 +234,11 @@ public class PlatformManagerUnixPlugin
 	}
 	
 	private void showScriptManualUpdateDialog(String newFilePath,
-			String oldFilePath, int version) {
-		UIFunctions uif = UIFunctionsManager.getUIFunctions();
+			String oldFilePath, final int version) {
+		final UIFunctions uif = UIFunctionsManager.getUIFunctions();
 		if (uif != null) {
-			String sCopyLine = "cp \"" + newFilePath + "\" \"" + oldFilePath + "\"";
-			int answer = uif.promptUser(
+			final String sCopyLine = "cp \"" + newFilePath + "\" \"" + oldFilePath + "\"";
+			uif.promptUser(
 					MessageText.getString("unix.script.new.title"),
 					MessageText.getString("unix.script.new.text", new String[] {
 						newFilePath,
@@ -246,32 +247,37 @@ public class PlatformManagerUnixPlugin
 						MessageText.getString("unix.script.new.button.quit"),
 						MessageText.getString("unix.script.new.button.continue"),
 						MessageText.getString("unix.script.new.button.asknomore"),
-					}, 0, null, null, false, 0);
-			if (answer == 0) {
-				System.out.println("The line you should run:\n" + sCopyLine);
-				uif.dispose(false, false);
-			} else if (answer == 2) {
-				COConfigurationManager.setParameter("unix.script.lastaskversion",
-						version);
-			}
+					}, 0, null, null, false, 0, new UserPrompterResultListener() {
+						public void prompterClosed(int answer) {
+							if (answer == 0) {
+								System.out.println("The line you should run:\n" + sCopyLine);
+								uif.dispose(false, false);
+							} else if (answer == 2) {
+								COConfigurationManager.setParameter("unix.script.lastaskversion",
+										version);
+							}
+						}
+					});
 		} else {
 			System.out.println("NO UIF");
 		}
 	}
 
 	private void showScriptAutoUpdateDialog() {
-		UIFunctions uif = UIFunctionsManager.getUIFunctions();
+		final UIFunctions uif = UIFunctionsManager.getUIFunctions();
 		if (uif != null) {
-			int answer = uif.promptUser(
-					MessageText.getString("unix.script.new.auto.title"),
-					MessageText.getString("unix.script.new.auto.text", new String[] {
-					}), new String[] {
+			uif.promptUser(MessageText.getString("unix.script.new.auto.title"),
+					MessageText.getString("unix.script.new.auto.text", new String[] {}),
+					new String[] {
 						MessageText.getString("UpdateWindow.restart"),
 						MessageText.getString("UpdateWindow.restartLater"),
-					}, 0, null, null, false, 0);
-			if (answer == 0) {
-				uif.dispose(true, false);
-			}
+					}, 0, null, null, false, 0, new UserPrompterResultListener() {
+						public void prompterClosed(int answer) {
+							if (answer == 0) {
+								uif.dispose(true, false);
+							}
+						}
+					});
 		} else {
 			System.out.println("NO UIF");
 		}
diff --git a/org/gudy/azureus2/platform/win32/PlatformManagerImpl.java b/org/gudy/azureus2/platform/win32/PlatformManagerImpl.java
index 61e1621..f27387f 100644
--- a/org/gudy/azureus2/platform/win32/PlatformManagerImpl.java
+++ b/org/gudy/azureus2/platform/win32/PlatformManagerImpl.java
@@ -51,7 +51,7 @@ PlatformManagerImpl
 	public static final int			RT_AZ 		= 1;
 	public static final int			RT_OTHER 	= 2;
 	
-	public static final String					DLL_NAME = "aereg";
+	public static String					DLL_NAME = "aereg";
 	
 	public static final String				VUZE_ASSOC		= "Vuze";
 	public static final String				NEW_MAIN_ASSOC	= "Azureus";
@@ -67,6 +67,12 @@ PlatformManagerImpl
 
 	private List	listeners = new ArrayList();
 	
+	static {
+		if (System.getProperty("os.arch", "").contains("64")) {
+			DLL_NAME += "64";
+		}
+	}
+	
 	public static PlatformManagerImpl
 	getSingleton()
 	
diff --git a/org/gudy/azureus2/platform/win32/access/impl/Release/aereg64.dll b/org/gudy/azureus2/platform/win32/access/impl/Release/aereg64.dll
new file mode 100644
index 0000000..cda2ac7
Binary files /dev/null and b/org/gudy/azureus2/platform/win32/access/impl/Release/aereg64.dll differ
diff --git a/org/gudy/azureus2/plugins/PluginEvent.java b/org/gudy/azureus2/plugins/PluginEvent.java
index f5d01ea..884d922 100644
--- a/org/gudy/azureus2/plugins/PluginEvent.java
+++ b/org/gudy/azureus2/plugins/PluginEvent.java
@@ -29,7 +29,13 @@ package org.gudy.azureus2.plugins;
 public interface 
 PluginEvent 
 {
+	/**
+	 * Not guaranteed to trigger.  Used to be triggered at startup
+	 */
 	public static final int	PEV_CONFIGURATION_WIZARD_STARTS			= 1;
+	/**
+	 * Not guaranteed to trigger.  Used to be triggered at startup
+	 */
 	public static final int	PEV_CONFIGURATION_WIZARD_COMPLETES		= 2;
 	public static final int	PEV_INITIALISATION_PROGRESS_TASK		= 3;
 	public static final int	PEV_INITIALISATION_PROGRESS_PERCENT		= 4;
diff --git a/org/gudy/azureus2/plugins/PluginManagerDefaults.java b/org/gudy/azureus2/plugins/PluginManagerDefaults.java
index 324f1ba..810dd01 100644
--- a/org/gudy/azureus2/plugins/PluginManagerDefaults.java
+++ b/org/gudy/azureus2/plugins/PluginManagerDefaults.java
@@ -52,6 +52,7 @@ PluginManagerDefaults
 	public static final String	PID_TRACKER_PEER_AUTH		= "Tracker Peer Auth";
 	public static final String	PID_NET_STATUS				= "Network Status";
 	public static final String	PID_BUDDY					= "Buddy";
+	public static final String	PID_RSS						= "RSS";
 	
 	public static final String[] PLUGIN_IDS = {
 			
@@ -74,6 +75,7 @@ PluginManagerDefaults
 			PID_TRACKER_PEER_AUTH,
 			PID_NET_STATUS,
 			PID_BUDDY,
+			PID_RSS,
 		};
 	
 	public String[]
diff --git a/org/gudy/azureus2/plugins/PluginState.java b/org/gudy/azureus2/plugins/PluginState.java
index 2d2eac8..e03c1c0 100644
--- a/org/gudy/azureus2/plugins/PluginState.java
+++ b/org/gudy/azureus2/plugins/PluginState.java
@@ -87,7 +87,12 @@ public interface PluginState {
 	  public void uninstall() throws PluginException;
 	
 	  public boolean isShared();
+	  
 	  public boolean isUnloadable();
+	  
+	  public boolean isUnloaded();
+	  
 	  public void unload() throws PluginException;
+	  
 	  public void reload() throws PluginException;
 }
diff --git a/org/gudy/azureus2/plugins/ddb/DistributedDatabase.java b/org/gudy/azureus2/plugins/ddb/DistributedDatabase.java
index df87c42..c89ffbe 100644
--- a/org/gudy/azureus2/plugins/ddb/DistributedDatabase.java
+++ b/org/gudy/azureus2/plugins/ddb/DistributedDatabase.java
@@ -77,6 +77,13 @@ DistributedDatabase
 	
 		throws DistributedDatabaseException;
 	
+	public DistributedDatabaseContact
+	importContact(
+		InetSocketAddress				address,
+		byte							protocol_version )
+	
+		throws DistributedDatabaseException;
+	
 	public void
 	write(
 		DistributedDatabaseListener		listener,
diff --git a/org/gudy/azureus2/plugins/ddb/DistributedDatabaseContact.java b/org/gudy/azureus2/plugins/ddb/DistributedDatabaseContact.java
index b1b947c..903fbe2 100644
--- a/org/gudy/azureus2/plugins/ddb/DistributedDatabaseContact.java
+++ b/org/gudy/azureus2/plugins/ddb/DistributedDatabaseContact.java
@@ -42,6 +42,13 @@ DistributedDatabaseContact
 	isAlive(
 		long		timeout );
 	
+		// async version - event types: complete -> alive, timeout -> dead
+	
+	public void
+	isAlive(
+		long							timeout,
+		DistributedDatabaseListener		listener );
+	
 	public boolean
 	isOrHasBeenLocal();
 	
diff --git a/org/gudy/azureus2/plugins/download/Download.java b/org/gudy/azureus2/plugins/download/Download.java
index 21d5d29..68f3295 100644
--- a/org/gudy/azureus2/plugins/download/Download.java
+++ b/org/gudy/azureus2/plugins/download/Download.java
@@ -199,6 +199,14 @@ Download extends DownloadEventNotifier
 	 */
 	public void setFlag(long flag, boolean set);
 
+	/**
+	 * get all the flags as a bitmap
+	 * @since 4209
+	 * @return
+	 */
+	
+	public long
+	getFlags();
 	
 	/**
 	 * Index of download. {@link #getPosition()}
diff --git a/org/gudy/azureus2/plugins/sharing/ShareManagerListener.java b/org/gudy/azureus2/plugins/sharing/ShareManagerListener.java
index 403eea8..0c1fb77 100644
--- a/org/gudy/azureus2/plugins/sharing/ShareManagerListener.java
+++ b/org/gudy/azureus2/plugins/sharing/ShareManagerListener.java
@@ -34,7 +34,8 @@ ShareManagerListener
 	
 	public void
 	resourceModified(
-		ShareResource		resource );
+		ShareResource		old_resource,
+		ShareResource		new_resource );
 	
 	public void
 	resourceDeleted(
diff --git a/org/gudy/azureus2/plugins/ui/UIInputReceiver.java b/org/gudy/azureus2/plugins/ui/UIInputReceiver.java
index afea741..43fac22 100644
--- a/org/gudy/azureus2/plugins/ui/UIInputReceiver.java
+++ b/org/gudy/azureus2/plugins/ui/UIInputReceiver.java
@@ -180,10 +180,23 @@ public interface UIInputReceiver {
 	 * This prompts the user for input. This method will not return until
 	 * the user has either entered valid input, or signalled they want to
 	 * cancel entering any data.
+	 * 
+	 * @deprecated Use {@link #prompt(UIInputReceiverListener)}
 	 */
+	@Deprecated
 	public void prompt();
 	
 	/**
+	 * This prompts the user for input and returns immediately.  When the user
+	 * has closed the input ui, the {@link UIInputReceiverListener} will
+	 * be triggered
+	 * 
+	 * @param receiver_listener
+	 * @since 4.2.0.9
+	 */
+	public void prompt(UIInputReceiverListener receiver_listener);
+	
+	/**
 	 * Returns <tt>true</tt> if the user submitted any data.
 	 */
 	public boolean hasSubmittedInput();
diff --git a/org/gudy/azureus2/plugins/ui/UIInputReceiverListener.java b/org/gudy/azureus2/plugins/ui/UIInputReceiverListener.java
new file mode 100644
index 0000000..96a6c6a
--- /dev/null
+++ b/org/gudy/azureus2/plugins/ui/UIInputReceiverListener.java
@@ -0,0 +1,6 @@
+package org.gudy.azureus2.plugins.ui;
+
+public interface UIInputReceiverListener
+{
+	public void UIInputReceiverClosed(UIInputReceiver receiver);
+}
diff --git a/org/gudy/azureus2/plugins/utils/Utilities.java b/org/gudy/azureus2/plugins/utils/Utilities.java
index 3f09b46..bf96911 100644
--- a/org/gudy/azureus2/plugins/utils/Utilities.java
+++ b/org/gudy/azureus2/plugins/utils/Utilities.java
@@ -41,6 +41,8 @@ import org.gudy.azureus2.plugins.utils.search.SearchException;
 import org.gudy.azureus2.plugins.utils.search.SearchInitiator;
 import org.gudy.azureus2.plugins.utils.search.SearchProvider;
 import org.gudy.azureus2.plugins.utils.security.*;
+import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionException;
+import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionManager;
 import org.gudy.azureus2.plugins.utils.xml.simpleparser.*;
 import org.gudy.azureus2.plugins.utils.xml.rss.*;
 
@@ -287,6 +289,12 @@ Utilities
  		Map		data,
  		boolean	use_backup );	
 	
+	public void
+ 	deleteResilientBEncodedFile(
+ 		File	parent_dir,
+ 		String	file_name,
+ 		boolean	use_backup );
+	
 	/**
 	 * Compares two version strings for order. 
 	 * Returns a negative integer, zero, or a positive integer as the first 
@@ -342,6 +350,34 @@ Utilities
 	getSearchInitiator()
 	
 		throws SearchException;
+	
+	public SubscriptionManager
+	getSubscriptionManager()
+	
+		throws SubscriptionException;
+	
+	public boolean
+	isFeatureEnabled(
+		String					feature_id,
+		Map<String,Object>		feature_properties );
+	
+	public void
+	registerFeatureEnabler(
+		FeatureEnabler	enabler );
+	
+	public void
+	unregisterFeatureEnabler(
+		FeatureEnabler	enabler );
+	
+	public interface
+	FeatureEnabler
+	{
+		public boolean
+		isFeatureEnabled(
+			String					requester_id,
+			String					feature_id,
+			Map<String,Object>		feature_properties );
+	}
 }
 
 
diff --git a/org/gudy/azureus2/plugins/utils/subscriptions/Subscription.java b/org/gudy/azureus2/plugins/utils/subscriptions/Subscription.java
new file mode 100644
index 0000000..3bf4a29
--- /dev/null
+++ b/org/gudy/azureus2/plugins/utils/subscriptions/Subscription.java
@@ -0,0 +1,35 @@
+/*
+ * Created on Oct 7, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package org.gudy.azureus2.plugins.utils.subscriptions;
+
+public interface 
+Subscription 
+{
+	public String
+	getID();
+	
+	public String
+	getName();
+	
+	public SubscriptionResult[]
+	getResults();
+}
diff --git a/org/gudy/azureus2/plugins/utils/subscriptions/SubscriptionException.java b/org/gudy/azureus2/plugins/utils/subscriptions/SubscriptionException.java
new file mode 100644
index 0000000..69db3de
--- /dev/null
+++ b/org/gudy/azureus2/plugins/utils/subscriptions/SubscriptionException.java
@@ -0,0 +1,42 @@
+/*
+ * Created on Jun 20, 2008
+ * Created by Paul Gardner
+ * 
+ * Copyright 2008 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package org.gudy.azureus2.plugins.utils.subscriptions;
+
+public class 
+SubscriptionException 
+	extends Exception
+{
+	public
+	SubscriptionException(
+		String		str )
+	{
+		super( str );
+	}
+	
+	public
+	SubscriptionException(
+		String		str,
+		Throwable 	e )
+	{
+		super( str, e );
+	}
+}
diff --git a/org/gudy/azureus2/plugins/utils/subscriptions/SubscriptionManager.java b/org/gudy/azureus2/plugins/utils/subscriptions/SubscriptionManager.java
new file mode 100644
index 0000000..f83802f
--- /dev/null
+++ b/org/gudy/azureus2/plugins/utils/subscriptions/SubscriptionManager.java
@@ -0,0 +1,29 @@
+/*
+ * Created on Oct 7, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package org.gudy.azureus2.plugins.utils.subscriptions;
+
+public interface 
+SubscriptionManager 
+{
+	public Subscription[] 
+	getSubscriptions();
+}
diff --git a/org/gudy/azureus2/plugins/utils/subscriptions/SubscriptionResult.java b/org/gudy/azureus2/plugins/utils/subscriptions/SubscriptionResult.java
new file mode 100644
index 0000000..e15c84e
--- /dev/null
+++ b/org/gudy/azureus2/plugins/utils/subscriptions/SubscriptionResult.java
@@ -0,0 +1,40 @@
+/*
+ * Created on Oct 7, 2009
+ * Created by Paul Gardner
+ * 
+ * Copyright 2009 Vuze, Inc.  All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+package org.gudy.azureus2.plugins.utils.subscriptions;
+
+public interface 
+SubscriptionResult 
+{
+		// this maps to the SearchResult properties (well, some subset ) 
+	
+	public Object
+	getProperty(
+		int		property_name );
+	
+	public boolean
+	isRead();
+	
+	public void
+	setRead(
+		boolean	read );
+	
+}
diff --git a/org/gudy/azureus2/pluginsimpl/local/PluginCoreUtils.java b/org/gudy/azureus2/pluginsimpl/local/PluginCoreUtils.java
index 024b115..284cd3e 100644
--- a/org/gudy/azureus2/pluginsimpl/local/PluginCoreUtils.java
+++ b/org/gudy/azureus2/pluginsimpl/local/PluginCoreUtils.java
@@ -38,7 +38,6 @@ import org.gudy.azureus2.plugins.peers.PeerManager;
 import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.plugins.tracker.TrackerTorrent;
 
-import org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerFileInfoImpl;
 import org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerImpl;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl;
diff --git a/org/gudy/azureus2/pluginsimpl/local/PluginInitializer.java b/org/gudy/azureus2/pluginsimpl/local/PluginInitializer.java
index e5a4a3b..ccab1fd 100644
--- a/org/gudy/azureus2/pluginsimpl/local/PluginInitializer.java
+++ b/org/gudy/azureus2/pluginsimpl/local/PluginInitializer.java
@@ -169,6 +169,12 @@ PluginInitializer
 					"azbuddy",
 					"true",
 					"false"},
+			{	 PluginManagerDefaults.PID_RSS, 
+					"com.aelitis.azureus.core.rssgen.RSSGeneratorPlugin", 
+					"azintrss", 
+					"azintrss",
+					"true",
+					"false"},
 			/* disable until we can get some tracker admins to work on this
 	   		{	 PluginManagerDefaults.PID_TRACKER_PEER_AUTH, 
 					"com.aelitis.azureus.plugins.tracker.peerauth.TrackerPeerAuthPlugin", 
@@ -1076,6 +1082,33 @@ PluginInitializer
 	      
 	      String pid = plugin_id[0]==null?directory.getName():plugin_id[0];
 	      
+	      if ( pid.endsWith( "_v" )){
+	    	  
+	    	  	// re-verify jar files
+	    	  
+	    	  log( "Re-verifying " + pid );
+	    	  
+	    	  for( int i = 0 ; i < pluginContents.length ; i++){
+	    	    	
+	    	    	File	jar_file = pluginContents[i];
+	    	    	
+	    	    	if ( jar_file.getName().endsWith( ".jar" )){
+	    	    		
+	    	    		try{
+	    	    			log( "    verifying " + jar_file );
+	    	    			
+	    	    			AEVerifier.verifyData( jar_file );
+	    	    			
+	    	    			log( "    OK" );
+	    	    		}catch( Throwable e ){
+	    	    			
+	    	    			log( "    Failed" );
+	    	    			
+	    	    			throw( e );
+	    	    		}
+	    	    	}
+	    	   }
+	      }
 	      Plugin plugin = PluginLauncherImpl.getPreloadedPlugin( plugin_class );
 	      
 	      if ( plugin == null ){
@@ -1190,6 +1223,15 @@ PluginInitializer
     }
   }
   
+  private void
+  log(
+	String	str )
+  {
+	if (Logger.isEnabled()){
+		Logger.log(new LogEvent(LOGID, str ));
+	}
+  }
+  
   public void 
   initialisePlugins() 
   {
diff --git a/org/gudy/azureus2/pluginsimpl/local/PluginStateImpl.java b/org/gudy/azureus2/pluginsimpl/local/PluginStateImpl.java
index f56f329..a0730fa 100644
--- a/org/gudy/azureus2/pluginsimpl/local/PluginStateImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/PluginStateImpl.java
@@ -122,6 +122,12 @@ public class PluginStateImpl implements PluginState {
 		PluginInstallerImpl.getSingleton(pi.getPluginManager()).uninstall(this.pi);
 	}
 
+	public boolean 
+	isUnloaded() 
+	{
+		return( pi.class_loader == null );
+	}
+	
 	public void unload() throws PluginException {
 		unload( false );
 	}
diff --git a/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseContactImpl.java b/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseContactImpl.java
index 7a80e10..2e18fbb 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseContactImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseContactImpl.java
@@ -25,13 +25,18 @@ package org.gudy.azureus2.pluginsimpl.local.ddb;
 import java.net.InetSocketAddress;
 
 import org.gudy.azureus2.plugins.ddb.DistributedDatabaseContact;
+import org.gudy.azureus2.plugins.ddb.DistributedDatabaseEvent;
 import org.gudy.azureus2.plugins.ddb.DistributedDatabaseException;
 import org.gudy.azureus2.plugins.ddb.DistributedDatabaseKey;
+import org.gudy.azureus2.plugins.ddb.DistributedDatabaseKeyStats;
+import org.gudy.azureus2.plugins.ddb.DistributedDatabaseListener;
 import org.gudy.azureus2.plugins.ddb.DistributedDatabaseProgressListener;
 import org.gudy.azureus2.plugins.ddb.DistributedDatabaseTransferType;
 import org.gudy.azureus2.plugins.ddb.DistributedDatabaseValue;
 
 import com.aelitis.azureus.plugins.dht.DHTPluginContact;
+import com.aelitis.azureus.plugins.dht.DHTPluginOperationListener;
+import com.aelitis.azureus.plugins.dht.DHTPluginValue;
 
 
 /**
@@ -74,6 +79,83 @@ DDBaseContactImpl
 		return( contact.isAlive( timeout ));
 	}
 	
+	public void
+	isAlive(
+		long								timeout,
+		final DistributedDatabaseListener	listener )
+	{
+			
+		contact.isAlive( 
+			timeout,
+			new DHTPluginOperationListener()
+			{
+				public void
+				starts(
+					byte[]				key )
+				{
+				}
+				
+				public void
+				diversified()
+				{
+				}
+				
+				public void
+				valueRead(
+					DHTPluginContact	originator,
+					DHTPluginValue		value )
+				{
+				}
+				
+				public void
+				valueWritten(
+					DHTPluginContact	target,
+					DHTPluginValue		value )
+				{
+				}
+				
+				public void
+				complete(
+					byte[]					key,
+					final boolean			timeout_occurred )
+				{
+					listener.event(
+						new DistributedDatabaseEvent()
+						{
+							public int
+							getType()
+							{
+								return( timeout_occurred?ET_OPERATION_TIMEOUT:ET_OPERATION_COMPLETE );
+							}
+							
+							public DistributedDatabaseKey
+							getKey()
+							{
+								return( null );
+							}
+							
+							public DistributedDatabaseKeyStats
+							getKeyStats()
+							{
+								return( null );
+							}
+							
+							public DistributedDatabaseValue
+							getValue()
+							{
+								return( null );
+							}
+							
+							public DistributedDatabaseContact
+							getContact()
+							{
+								return( DDBaseContactImpl.this );
+							}
+						});
+				}
+			});
+	}
+	
 	public boolean
 	isOrHasBeenLocal()
 	{
diff --git a/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseImpl.java b/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseImpl.java
index 46bb18d..11de6d2 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseImpl.java
@@ -288,6 +288,25 @@ DDBaseImpl
 		return( new DDBaseContactImpl( this, contact));
 	}
 	
+	public DistributedDatabaseContact
+	importContact(
+		InetSocketAddress				address,
+		byte							version )
+	
+		throws DistributedDatabaseException
+	{
+		throwIfNotAvailable();
+	
+		DHTPluginContact	contact = getDHT().importContact( address, version );
+		
+		if ( contact == null ){
+			
+			throw( new DistributedDatabaseException( "import of '" + address + "' failed" ));
+		}
+		
+		return( new DDBaseContactImpl( this, contact));
+	}
+	
 	public void
 	write(
 		DistributedDatabaseListener		listener,
@@ -541,7 +560,34 @@ DDBaseImpl
 		
 		transfer_map.put( type_key, handler );
 		
-		final String	handler_name = type==torrent_transfer?"Torrent Transfer":"Plugin Defined";
+		final String	handler_name;
+		
+		if ( type == torrent_transfer ){
+			
+			handler_name = "Torrent Transfer";
+			
+		}else{
+			
+			String class_name = type.getClass().getName();
+			
+			int	pos = class_name.indexOf( '$' );
+			
+			if ( pos != -1 ){
+				
+				class_name = class_name.substring( pos+1 );
+				
+			}else{
+			
+				pos = class_name.lastIndexOf( '.' );
+				
+				if ( pos != -1 ){
+					
+					class_name = class_name.substring( pos+1 );
+				}
+			}
+			
+			handler_name = "Plugin Defined (" + class_name + ")";
+		}
 		
 		getDHT().registerHandler(
 			type_key.getHash(),
diff --git a/org/gudy/azureus2/pluginsimpl/local/download/DownloadImpl.java b/org/gudy/azureus2/pluginsimpl/local/download/DownloadImpl.java
index f4fd135..411df6b 100644
--- a/org/gudy/azureus2/pluginsimpl/local/download/DownloadImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/download/DownloadImpl.java
@@ -267,6 +267,12 @@ DownloadImpl
 		return( download_manager.getErrorDetails());
 	}
 	
+	public long
+	getFlags()
+	{
+		return( download_manager.getDownloadState().getFlags());
+	}
+	
 	public boolean
 	getFlag(
 		long		flag )
diff --git a/org/gudy/azureus2/pluginsimpl/local/download/DownloadManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/download/DownloadManagerImpl.java
index 5740868..1107617 100644
--- a/org/gudy/azureus2/pluginsimpl/local/download/DownloadManagerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/download/DownloadManagerImpl.java
@@ -26,35 +26,36 @@ package org.gudy.azureus2.pluginsimpl.local.download;
  *
  */
 
-import java.util.*;
 import java.io.File;
 import java.net.URL;
+import java.util.*;
 
-import com.aelitis.azureus.core.*;
-import com.aelitis.azureus.core.util.CopyOnWriteList;
-
-import org.gudy.azureus2.plugins.torrent.*;
-import org.gudy.azureus2.plugins.ui.UIManagerEvent;
-import org.gudy.azureus2.pluginsimpl.local.torrent.*;
-import org.gudy.azureus2.pluginsimpl.local.ui.UIManagerImpl;
-import org.gudy.azureus2.plugins.download.DownloadException;
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.download.DownloadEventNotifier;
-import org.gudy.azureus2.plugins.download.DownloadManagerListener;
-import org.gudy.azureus2.plugins.download.DownloadManagerStats;
-import org.gudy.azureus2.plugins.download.DownloadRemovalVetoException;
-import org.gudy.azureus2.plugins.download.DownloadWillBeAddedListener;
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.disk.DiskManager;
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.download.DownloadManagerInitialisationAdapter;
+import org.gudy.azureus2.core3.download.impl.DownloadManagerDefaultPaths;
+import org.gudy.azureus2.core3.download.impl.DownloadManagerMoveHandler;
+import org.gudy.azureus2.core3.global.GlobalManager;
+import org.gudy.azureus2.core3.global.GlobalManagerDownloadRemovalVetoException;
+import org.gudy.azureus2.core3.global.GlobalManagerDownloadWillBeRemovedListener;
+import org.gudy.azureus2.core3.global.GlobalManagerListener;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentException;
+import org.gudy.azureus2.core3.util.AEMonitor;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.FileUtil;
+import org.gudy.azureus2.plugins.download.*;
 import org.gudy.azureus2.plugins.download.savelocation.DefaultSaveLocationManager;
 import org.gudy.azureus2.plugins.download.savelocation.SaveLocationManager;
+import org.gudy.azureus2.plugins.torrent.Torrent;
+import org.gudy.azureus2.plugins.torrent.TorrentException;
+import org.gudy.azureus2.plugins.ui.UIManagerEvent;
+import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentImpl;
+import org.gudy.azureus2.pluginsimpl.local.ui.UIManagerImpl;
 
-import org.gudy.azureus2.core3.torrent.*;
-import org.gudy.azureus2.core3.config.*;
-import org.gudy.azureus2.core3.global.*;
-import org.gudy.azureus2.core3.disk.DiskManager;
-import org.gudy.azureus2.core3.download.*;
-import org.gudy.azureus2.core3.download.impl.DownloadManagerMoveHandler;
-import org.gudy.azureus2.core3.download.impl.DownloadManagerDefaultPaths;
-import org.gudy.azureus2.core3.util.*;
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.util.CopyOnWriteList;
 
 
 public class 
@@ -756,6 +757,8 @@ DownloadManagerImpl
 			listeners = new_listeners;
 			if (notify_of_current_downloads) {
 				downloads_copy = new ArrayList(downloads);
+				// randomize list so that plugins triggering dlm-state fixups don't lock each other by doing everything in the same order
+				Collections.shuffle(downloads_copy);
 			}
 		}
 		finally {
diff --git a/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignDelegate.java b/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignDelegate.java
index 50d40f2..5030258 100644
--- a/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignDelegate.java
+++ b/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignDelegate.java
@@ -28,12 +28,16 @@ package org.gudy.azureus2.pluginsimpl.local.peers;
  *
  */
 
-import java.util.*;
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import org.gudy.azureus2.core3.disk.DiskManager;
 import org.gudy.azureus2.core3.disk.DiskManagerReadRequest;
 import org.gudy.azureus2.core3.peer.*;
-import org.gudy.azureus2.core3.peer.impl.*;
+import org.gudy.azureus2.core3.peer.impl.PEPeerControl;
+import org.gudy.azureus2.core3.peer.impl.PEPeerTransport;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.network.Connection;
 import org.gudy.azureus2.plugins.peers.*;
@@ -44,7 +48,8 @@ import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
 import com.aelitis.azureus.core.networkmanager.NetworkConnectionBase;
 import com.aelitis.azureus.core.networkmanager.NetworkManager;
 import com.aelitis.azureus.core.peermanager.messaging.Message;
-import com.aelitis.azureus.core.peermanager.peerdb.*;
+import com.aelitis.azureus.core.peermanager.peerdb.PeerItem;
+import com.aelitis.azureus.core.peermanager.peerdb.PeerItemFactory;
 import com.aelitis.azureus.core.peermanager.piecepicker.util.BitFlags;
 
 public class 
@@ -120,6 +125,8 @@ PeerForeignDelegate
      * Should never be called
      */
     public void sendUnChoke() {}
+    
+    public InetAddress getAlternativeIPv6() {  return null; }
 
     
  
@@ -874,7 +881,7 @@ PeerForeignDelegate
      */
 	public void clearAvailabilityAdded() {};
 	
-	public PEPeerTransport reconnect(boolean tryUDP){ return null; }
+	public PEPeerTransport reconnect(boolean tryUDP, boolean tryIPv6){ return null; }
 	public boolean isSafeForReconnect() { return false; }
 	
 	public void setUploadRateLimitBytesPerSecond( int bytes ){ network_connection.setUploadLimit( bytes ); }
diff --git a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareManagerImpl.java
index 4e693db..87fbb79 100644
--- a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareManagerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareManagerImpl.java
@@ -95,12 +95,12 @@ ShareManagerImpl
 	private URL[]				announce_urls;
 	private ShareConfigImpl		config;
 	
-	private Map					shares 		= new HashMap();
+	private Map<String,ShareResourceImpl>	shares 		= new HashMap<String, ShareResourceImpl>();
 	
 	private shareScanner		current_scanner;
 	private boolean				scanning;
 	
-	private List				listeners	= new ArrayList();
+	private List<ShareManagerListener>				listeners	= new ArrayList<ShareManagerListener>();
 	
 	protected
 	ShareManagerImpl()
@@ -147,11 +147,11 @@ ShareManagerImpl
 										
 					}finally{
 					
-						Iterator it = shares.values().iterator();
+						Iterator<ShareResourceImpl> it = shares.values().iterator();
 						
 						while(it.hasNext()){
 						
-							ShareResourceImpl	resource = (ShareResourceImpl)it.next();
+							ShareResourceImpl	resource = it.next();
 							
 							if ( resource.getType() == ShareResource.ST_DIR_CONTENTS ){
 					
@@ -159,7 +159,7 @@ ShareManagerImpl
 									
 									try{
 										
-										((ShareManagerListener)listeners.get(i)).resourceAdded( resource );
+										listeners.get(i).resourceAdded( resource );
 										
 									}catch( Throwable e ){
 										
@@ -257,11 +257,11 @@ ShareManagerImpl
 	{
 			// copy set for iteration as consistency check can delete resource
 		
-		Iterator	it = new HashSet(shares.values()).iterator();
+		Iterator<ShareResourceImpl>	it = new HashSet<ShareResourceImpl>(shares.values()).iterator();
 		
 		while(it.hasNext()){
 			
-			ShareResourceImpl	resource = (ShareResourceImpl)it.next();
+			ShareResourceImpl	resource = it.next();
 			
 			try{
 				resource.checkConsistency();
@@ -294,7 +294,7 @@ ShareManagerImpl
 			
 			if ( new_resource != null ){
 				
-				ShareResourceImpl	old_resource = (ShareResourceImpl)shares.get(new_resource.getName());
+				ShareResourceImpl	old_resource = shares.get(new_resource.getName());
 				
 				if ( old_resource != null ){
 					
@@ -530,7 +530,7 @@ ShareManagerImpl
 					+ file.toString() + "'"));
 
 		try{
-			return( (ShareResourceFile)addFileOrDir( parent, file, ShareResource.ST_FILE, false ));
+			return( (ShareResourceFile)addFileOrDir( parent, file, ShareResource.ST_FILE ));
 			
 		}catch( ShareException e ){
 			
@@ -572,7 +572,7 @@ ShareManagerImpl
 		try{
 			this_mon.enter();
 			
-			return( (ShareResourceDir)addFileOrDir( parent, dir, ShareResource.ST_DIR, false ));
+			return( (ShareResourceDir)addFileOrDir( parent, dir, ShareResource.ST_DIR ));
 			
 		}catch( ShareException e ){
 			
@@ -599,8 +599,7 @@ ShareManagerImpl
 	addFileOrDir(
 		ShareResourceDirContentsImpl	parent,
 		File							file,
-		int								type,
-		boolean							modified )
+		int								type )
 	
 		throws ShareException, ShareResourceDeletionVetoException
 	{
@@ -609,11 +608,13 @@ ShareManagerImpl
 		
 			String	name = file.getCanonicalFile().toString();
 			
-			ShareResource	old_resource = (ShareResource)shares.get(name);
+			ShareResourceImpl	old_resource = shares.get(name);
 			
-			if ( old_resource != null ){
+			boolean	modified = old_resource != null;
+			
+			if ( modified ){
 		
-				old_resource.delete();
+				old_resource.delete( true, false );
 			}
 			
 			ShareResourceImpl new_resource;
@@ -641,7 +642,7 @@ ShareManagerImpl
 					
 					if ( modified ){
 						
-						((ShareManagerListener)listeners.get(i)).resourceModified( new_resource );
+						((ShareManagerListener)listeners.get(i)).resourceModified( old_resource, new_resource );
 					
 					}else{
 						
@@ -689,10 +690,10 @@ ShareManagerImpl
 			
 			if ( old_resource != null ){
 				
-				old_resource.delete();
+				old_resource.delete( true );
 			}
 
-			ShareResourceDirContents new_resource = new ShareResourceDirContentsImpl( this, dir, recursive, true );
+			ShareResourceDirContentsImpl new_resource = new ShareResourceDirContentsImpl( this, dir, recursive, true );
 						
 			shares.put( name, new_resource );
 			
@@ -732,7 +733,8 @@ ShareManagerImpl
 	
 	protected void
 	delete(
-		ShareResourceImpl	resource )
+		ShareResourceImpl	resource,
+		boolean				fire_listeners )
 	
 		throws ShareException
 	{
@@ -749,15 +751,18 @@ ShareManagerImpl
 			
 			config.saveConfig();
 			
-			for (int i=0;i<listeners.size();i++){
+			if ( fire_listeners ){
 				
-				try{
-					
-					((ShareManagerListener)listeners.get(i)).resourceDeleted( resource );
-					
-				}catch( Throwable e ){
+				for (int i=0;i<listeners.size();i++){
 					
-					Debug.printStackTrace( e );
+					try{
+						
+						((ShareManagerListener)listeners.get(i)).resourceDeleted( resource );
+						
+					}catch( Throwable e ){
+						
+						Debug.printStackTrace( e );
+					}
 				}
 			}
 		}finally{
diff --git a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirContentsImpl.java b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirContentsImpl.java
index 50617d0..c45c75b 100644
--- a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirContentsImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirContentsImpl.java
@@ -187,7 +187,7 @@ ShareResourceDirContentsImpl
 				
 			}else{
 			
-				manager.delete( this );
+				manager.delete( this, true );
 			}
 		}else{
 					
diff --git a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileOrDirImpl.java b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileOrDirImpl.java
index 230ca54..d3ba472 100644
--- a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileOrDirImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileOrDirImpl.java
@@ -310,11 +310,11 @@ ShareResourceFileOrDirImpl
 				}
 			}else{
 				
-				manager.addFileOrDir( null, file, getType(), true );
+				manager.addFileOrDir( null, file, getType());
 			}
 		}catch( Throwable e ){
-						
-			manager.delete( this );
+							
+			manager.delete( this, true );
 		}
 	}
 	
diff --git a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceImpl.java b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceImpl.java
index 269da12..cd47089 100644
--- a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceImpl.java
@@ -282,12 +282,22 @@ ShareResourceImpl
 	
 		throws ShareException, ShareResourceDeletionVetoException
 	{
+		delete( force, true );
+	}
+	
+	public void
+	delete(
+		boolean	force,
+		boolean	fire_listeners )
+	
+		throws ShareException, ShareResourceDeletionVetoException
+	{
 		if ( !force ){
 	
 			canBeDeleted();
 		}
 		
-		manager.delete(this);
+		manager.delete( this, fire_listeners );
 	}
 	
 	public abstract boolean
diff --git a/org/gudy/azureus2/pluginsimpl/local/sharing/test/ShareTester.java b/org/gudy/azureus2/pluginsimpl/local/sharing/test/ShareTester.java
index e825012..ddd676e 100644
--- a/org/gudy/azureus2/pluginsimpl/local/sharing/test/ShareTester.java
+++ b/org/gudy/azureus2/pluginsimpl/local/sharing/test/ShareTester.java
@@ -257,9 +257,10 @@ ShareTester
 	
 	public void
 	resourceModified(
-		ShareResource		resource )
+		ShareResource		old_resource ,
+		ShareResource		new_resource )
 	{
-		System.out.println( "resource modified:" + resource.getName());
+		System.out.println( "resource modified:" + old_resource.getName());
 	}
 	
 	public void
diff --git a/org/gudy/azureus2/pluginsimpl/local/test/Test.java b/org/gudy/azureus2/pluginsimpl/local/test/Test.java
index 41e466e..8b5c262 100644
--- a/org/gudy/azureus2/pluginsimpl/local/test/Test.java
+++ b/org/gudy/azureus2/pluginsimpl/local/test/Test.java
@@ -55,6 +55,10 @@ import org.gudy.azureus2.plugins.utils.search.SearchResult;
 import org.gudy.azureus2.plugins.utils.security.SEPublicKey;
 import org.gudy.azureus2.plugins.utils.security.SEPublicKeyLocator;
 import org.gudy.azureus2.plugins.utils.security.SESecurityManager;
+import org.gudy.azureus2.plugins.utils.subscriptions.Subscription;
+import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionManager;
+import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionResult;
+
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.security.CryptoManagerPasswordHandler;
 import com.aelitis.azureus.core.security.CryptoManagerPasswordHandler.passwordDetails;
@@ -107,6 +111,29 @@ Test
 										e.printStackTrace();
 									}
 									
+									try{
+										SubscriptionManager sm = plugin_interface.getUtilities().getSubscriptionManager();
+									
+										Subscription[] subs = sm.getSubscriptions();
+										
+										for ( Subscription s: subs ){
+											
+											System.out.println( "subs: " + s.getName());
+											
+											SubscriptionResult[] results = s.getResults();
+											
+											for ( SubscriptionResult result: results ){
+												
+												System.out.println( "    " + result.getProperty( SearchResult.PR_NAME ) + ", read=" + result.isRead());
+											}
+											
+										}
+									}catch( Throwable e ){
+										
+										e.printStackTrace();
+									}
+									
+									/*
 									while( true ){
 										
 										try{
@@ -168,7 +195,7 @@ Test
 													
 													System.out.println( "waiting for results" );
 												}
-												*/
+												
 												
 												
 												Search s = si.createSearch(	providers, properties, null );
@@ -204,6 +231,7 @@ Test
 											e.printStackTrace();
 										}
 									}
+									*/
 								}
 							};
 							
diff --git a/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerWebPageResponseImpl.java b/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerWebPageResponseImpl.java
index 5dd6710..d37918d 100644
--- a/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerWebPageResponseImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerWebPageResponseImpl.java
@@ -262,7 +262,27 @@ TrackerWebPageResponseImpl
 
 			reply_header += name + ": " + value + NL;
 		}
+		
+		if ( do_gzip ){
 
+				// try and set the content-length to that of the compressed data
+			
+			if ( reply_bytes.length < 512*1024 ){
+				
+				ByteArrayOutputStream temp = new ByteArrayOutputStream( reply_bytes.length );
+				
+				GZIPOutputStream gzos = new GZIPOutputStream(temp);
+				
+				gzos.write( reply_bytes );
+				
+				gzos.finish();
+				
+				reply_bytes = temp.toByteArray();
+				
+				do_gzip = false;
+			}
+		}
+		
 		reply_header +=
 			"Content-Length: " + reply_bytes.length + NL +
 			NL;
@@ -302,7 +322,7 @@ TrackerWebPageResponseImpl
 
 			// make sure some fool isn't trying to use ../../ to escape from web dir
 
-		if ( !canonical_file.toString().startsWith( root_dir )){
+		if ( !canonical_file.toString().toLowerCase().startsWith( root_dir.toLowerCase())){
 
 			return( false );
 		}
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/AbstractUIInputReceiver.java b/org/gudy/azureus2/pluginsimpl/local/ui/AbstractUIInputReceiver.java
index d81b199..cd9cc21 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ui/AbstractUIInputReceiver.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ui/AbstractUIInputReceiver.java
@@ -22,6 +22,7 @@ package org.gudy.azureus2.pluginsimpl.local.ui;
 
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.plugins.ui.UIInputReceiver;
+import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
 import org.gudy.azureus2.plugins.ui.UIInputValidator;
 
 /**
@@ -110,6 +111,8 @@ public abstract class AbstractUIInputReceiver implements UIInputReceiver {
 	}
 	
 	private boolean result_recorded = false;
+	
+	protected UIInputReceiverListener receiver_listener;
 
 	public final void prompt() {
 		assertPrePrompt();
@@ -120,6 +123,21 @@ public abstract class AbstractUIInputReceiver implements UIInputReceiver {
 		this.prompted = true;
 	}
 	
+	public final void prompt(UIInputReceiverListener receiver_listener) {
+		assertPrePrompt();
+		this.receiver_listener = receiver_listener;
+		this.promptForInput();
+	}
+	
+	public final void triggerReceiverListener() {
+		if (!result_recorded) {
+			throw new RuntimeException(this.toString() + " did not record a result.");
+		}
+		this.prompted = true;
+		if (receiver_listener != null) {
+			receiver_listener.UIInputReceiverClosed(this);
+		}
+	}
 	
 	private boolean result_input_submitted = false;
 	private String result_input = null;
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/components/UITextAreaImpl.java b/org/gudy/azureus2/pluginsimpl/local/ui/components/UITextAreaImpl.java
index b26f3e5..56591d3 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ui/components/UITextAreaImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ui/components/UITextAreaImpl.java
@@ -28,8 +28,6 @@ package org.gudy.azureus2.pluginsimpl.local.ui.components;
  */
 
 import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -47,17 +45,15 @@ UITextAreaImpl
 	private int	max_size		= DEFAULT_MAX_SIZE;
 	private int max_file_size = 20 * max_size;
 	
-	PrintWriter pw;
+	PoopWriter pw;
 	int current_file_size;
-	
-	File file;
-	
+	File poop_file;
 	boolean useFile = true;
 	
 	AEMonitor file_mon = new AEMonitor("filemon");
 	
-	LinkedList	delay_text	= new LinkedList();
-	int			delay_size	= 0;
+	LinkedList<String>	delay_text	= new LinkedList<String>();
+	int					delay_size	= 0;
 	
 	FrequencyLimitedDispatcher	dispatcher = 
 		new FrequencyLimitedDispatcher(
@@ -81,25 +77,23 @@ UITextAreaImpl
 	setText(
 		String		text )
 	{
-		if (useFile) {
-			try {
+		if ( useFile ){
+			
+			try{
 				file_mon.enter();
-				if (pw == null) {
-					try {
-						file = AETemporaryFileHandler.createTempFile();
-
-						FileWriter fr = new FileWriter(file);
-						pw = new PrintWriter(fr);
+				
+				if ( pw == null ){
+					
+					pw = new PoopWriter();
 
-						pw.print(text);
-						current_file_size = text.length();
-						pw.flush();
+					pw.print(text);
+					
+					current_file_size = text.length();
 
-						return;
-					} catch (IOException e) {
-					}
+					return;
 				}
-			} finally {
+			}finally{
+				
 				file_mon.exit();
 			}
 		}
@@ -125,19 +119,26 @@ UITextAreaImpl
 	appendText(
 		String		text )
 	{
-		if (useFile && pw != null) {
-			try {
+		if ( useFile && pw != null ){
+			
+			try{
 				file_mon.enter();
 				
-				// shrink the file occasionally
-				if(current_file_size > max_file_size)
-					getFileText();
+					// shrink the file occasionally
+				
+				if ( current_file_size > max_file_size ){
+					
+					current_file_size = getFileText().length();
+				}
 				
 				pw.print(text);
+				
 				current_file_size += text.length();
-				pw.flush();
+				
 				return;
-			} finally {
+				
+			}finally{
+				
 				file_mon.exit();
 			}
 		}
@@ -181,11 +182,11 @@ UITextAreaImpl
 				
 				StringBuffer sb = new StringBuffer( delay_size );
 				
-				Iterator	it = delay_text.iterator();
+				Iterator<String>	it = delay_text.iterator();
 				
 				while( it.hasNext()){
 				
-					sb.append((String)it.next());
+					sb.append( it.next());
 				}
 				
 				text = sb.toString();
@@ -208,8 +209,9 @@ UITextAreaImpl
 	public String
 	getText()
 	{
-		if (useFile && pw != null) {
-			return getFileText();
+		if ( useFile && pw != null ){
+			
+			return( getFileText());
 		}
 
 		return((String)getProperty( PT_VALUE ));
@@ -222,61 +224,132 @@ UITextAreaImpl
 		max_size	= _max_size;
 	}
 	
-	private String getFileText() {
-		boolean recreate = pw != null;
-
-		try {
+	private String 
+	getFileText() 
+	{
+		try{
 			file_mon.enter();
 
-			if (recreate) {
-				pw.close();
-			}
-
 			String text = null;
-			try {
-				text = FileUtil.readFileEndAsString(file, max_size);
-			} catch (IOException e) {
-				e.printStackTrace();
-			}
 
-			if (text == null) {
+			if ( pw != null ){
+				
+				pw.close();
+			
+				text = pw.getText();
+			}
+			
+			if ( text == null ){
+				
 				text = "";
 			}
 
-			if (recreate) {
-				try {
-					FileWriter fr = new FileWriter(file);
-					pw = new PrintWriter(fr);
-					pw.print(text);
-					current_file_size = text.length();
-				} catch (IOException e) {
-					useFile = false;
-					e.printStackTrace();
-				}
+			pw = null;
+			
+			if ( useFile ){
+			
+				pw = new PoopWriter();
+				
+				pw.print(text);
+				
+				current_file_size = text.length();
 			}
+			
 			return text;
-		} finally {
+			
+		}finally{
+			
 			file_mon.exit();
 		}
 	}
 	
-	public void addPropertyChangeListener(UIPropertyChangeListener l) {
-		if (useFile) {
-			if (pw != null) {
-				try {
-					file_mon.enter();
-
-					pw.close();
-					pw = null;
-				} finally {
-					file_mon.exit();
-				}
-			}
+	public void 
+	addPropertyChangeListener(
+		UIPropertyChangeListener l ) 
+	{
+		if ( useFile ){
 
 			useFile = false;
-			setText(getFileText());
+			
+			setText( getFileText());
 		}
 
 		super.addPropertyChangeListener(l);
 	}
+	
+	protected class
+	PoopWriter
+	{	
+		private StringBuffer	buffer = new StringBuffer(256);
+		
+		private PrintWriter		pw;
+		
+		public void
+		print(
+			String	text )
+		{
+			if ( pw == null ){
+				
+				buffer.append( text );
+				
+				if ( buffer.length() > 8*1024 ){
+					
+					if ( poop_file == null ){
+						
+						try{
+							poop_file = AETemporaryFileHandler.createTempFile();
+							
+						}catch( Throwable e ){
+						}
+					}
+					
+					if ( poop_file != null ){
+						
+						try{
+							pw = new PrintWriter( poop_file );
+						
+							pw.print( buffer.toString());
+							
+						}catch( Throwable e ){
+						}
+					}
+					
+					buffer.setLength( 0 );
+				}
+			}else{
+				
+				pw.print( text );
+			}
+		}
+		
+		public String
+		getText()
+		{
+			if ( poop_file == null ){
+				
+				return( buffer.toString());
+				
+			}else{
+				
+				try{
+					return( FileUtil.readFileEndAsString( poop_file, max_size ));
+					
+				}catch( Throwable e ){
+					
+					return( "" );
+				}
+			}
+		}
+		
+		public void
+		close()
+		{
+			if ( pw != null ){
+				
+				pw.close();
+				
+				pw = null;
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginConfigModelImpl.java b/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginConfigModelImpl.java
index de6a290..4fc580e 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginConfigModelImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginConfigModelImpl.java
@@ -268,7 +268,7 @@ BasicPluginConfigModelImpl
 		String		resource_name,
 		String		value )
 	{
-		InfoParameterImpl res = new InfoParameterImpl(configobj, key_prefix, resource_name, value );
+		InfoParameterImpl res = new InfoParameterImpl(configobj, resolveKey(resource_name), resource_name, value );
 		
 		parameters.add( res );
 		
@@ -317,7 +317,12 @@ BasicPluginConfigModelImpl
 		
 		for (int i=0;i<_parameters.length;i++){
 			
-			((ParameterImpl)_parameters[i]).setGroup( pg );
+			ParameterImpl parameter = (ParameterImpl)_parameters[i];
+			
+			if ( parameter != null ){
+			
+				parameter.setGroup( pg );
+			}
 		}
 		
 		return( pg );
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/UtilitiesImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/UtilitiesImpl.java
index 721b686..d577e33 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/UtilitiesImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/UtilitiesImpl.java
@@ -29,6 +29,7 @@ package org.gudy.azureus2.pluginsimpl.local.utils;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.File;
+import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.URL;
 import java.nio.ByteBuffer;
@@ -40,6 +41,7 @@ import org.gudy.azureus2.platform.PlatformManager;
 import org.gudy.azureus2.platform.PlatformManagerFactory;
 import org.gudy.azureus2.plugins.*;
 import org.gudy.azureus2.plugins.utils.*;
+import org.gudy.azureus2.plugins.utils.Utilities.FeatureEnabler;
 import org.gudy.azureus2.plugins.utils.resourcedownloader.*;
 import org.gudy.azureus2.plugins.utils.resourceuploader.ResourceUploaderFactory;
 import org.gudy.azureus2.plugins.utils.search.Search;
@@ -48,6 +50,10 @@ import org.gudy.azureus2.plugins.utils.search.SearchInitiator;
 import org.gudy.azureus2.plugins.utils.search.SearchListener;
 import org.gudy.azureus2.plugins.utils.search.SearchProvider;
 import org.gudy.azureus2.plugins.utils.security.SESecurityManager;
+import org.gudy.azureus2.plugins.utils.subscriptions.Subscription;
+import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionException;
+import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionManager;
+import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionResult;
 import org.gudy.azureus2.plugins.utils.xml.rss.RSSFeed;
 import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentException;
 import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentFactory;
@@ -86,6 +92,7 @@ import org.gudy.azureus2.core3.util.TimerEvent;
 import org.gudy.azureus2.core3.util.TimerEventPerformer;
 
 import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.core.versioncheck.VersionCheckClient;
 
 public class 
@@ -112,6 +119,8 @@ UtilitiesImpl
 	private static List<searchManager>		search_managers 	= new ArrayList<searchManager>();
 	private static List<Object[]>			search_providers	= new ArrayList<Object[]>();
 	
+	private static CopyOnWriteList<FeatureEnabler>	feature_enablers = new CopyOnWriteList<FeatureEnabler>();
+	
 	public
 	UtilitiesImpl(
 		AzureusCore			_core,
@@ -890,6 +899,15 @@ UtilitiesImpl
 		FileUtil.writeResilientFile( parent_dir, file_name, data, use_backup );
 	}
 
+	public void
+ 	deleteResilientBEncodedFile(
+ 		File	parent_dir,
+ 		String	file_name,
+ 		boolean	use_backup )
+	{
+		FileUtil.deleteResilientFile( new File( parent_dir, file_name ));
+	}
+	
 	public int compareVersions(String v1, String v2) {
 		return Constants.compareVersions( v1, v2 );
 	}
@@ -1037,6 +1055,48 @@ UtilitiesImpl
 		}
 	}
 	
+	public boolean 
+	isFeatureEnabled(
+		String 					feature_id,
+		Map<String, Object> 	feature_properties) 
+	{
+		String pid = pi.getPluginID();
+		
+		if ( !pid.endsWith( "_v" )){
+			
+			return( false );
+		}
+		
+		for ( FeatureEnabler fe: feature_enablers ){
+			
+			if ( fe.isFeatureEnabled( pid, feature_id, feature_properties)){
+				
+				return( true );
+			}
+		}
+		
+		return false;
+	}
+	
+	public void
+	registerFeatureEnabler(
+		FeatureEnabler	enabler )
+	{
+		if ( !pi.getPluginID().endsWith( "_v" )){
+						
+			return;
+		}
+		
+		feature_enablers.add( enabler );
+	}
+	
+	public void
+	unregisterFeatureEnabler(
+		FeatureEnabler	enabler )
+	{
+		feature_enablers.remove( enabler );
+	}
+	
 	public interface
 	searchManager
 		extends SearchInitiator
@@ -1048,6 +1108,134 @@ UtilitiesImpl
 	}
 		
 	
+	public SubscriptionManager 
+	getSubscriptionManager() 
+	
+		throws SubscriptionException
+	{
+		try{
+			Method m = Class.forName( "com.aelitis.azureus.core.subs.SubscriptionManagerFactory" ).getMethod( "getSingleton" );
+			
+			final PluginSubscriptionManager sm = (PluginSubscriptionManager)m.invoke( null );
+			
+			return( 
+				new SubscriptionManager()
+				{
+					public Subscription[] 
+					getSubscriptions() 
+					{
+						PluginSubscription[] p_subs = sm.getSubscriptions( true );
+						
+						Subscription[]	subs = new Subscription[ p_subs.length ];
+						
+						for ( int i=0;i<subs.length;i++ ){
+							
+							final PluginSubscription p_sub = p_subs[i];
+							
+							subs[i] = 
+								new Subscription()
+								{
+									public String 
+									getID() 
+									{
+										return( p_sub.getID());
+									}
+									
+									public String 
+									getName() 
+									{
+										return( p_sub.getName());
+									}
+									
+									public SubscriptionResult[] 
+									getResults() 
+									{
+										PluginSubscriptionResult[] p_results = p_sub.getResults( false );
+										
+										SubscriptionResult[] results = new SubscriptionResult[p_results.length];
+										
+										for (int i=0;i<results.length;i++){
+											
+											final PluginSubscriptionResult p_res = p_results[i];
+											
+											results[i] = 
+												new SubscriptionResult()
+												{
+													private Map<Integer,Object> map = p_res.toPropertyMap();
+													
+													public Object
+													getProperty(
+														int		property_name )
+													{
+														return( map.get( property_name ));
+													}
+													
+													public boolean
+													isRead()
+													{
+														return( p_res.getRead());
+													}
+													
+													public void
+													setRead(
+														boolean	read )
+													{
+														p_res.setRead( read );
+													}
+												};
+										}
+										
+										return( results );
+									}
+								};
+						}
+					
+						return( subs );
+					}
+				});
+			
+		}catch( Throwable e ){
+			
+			throw( new SubscriptionException( "Subscriptions unavailable", e ));
+		}
+	}
+	
+	public interface
+	PluginSubscriptionManager
+	{
+		public PluginSubscription[]
+		getSubscriptions(
+			boolean	subscribed_only );
+	}
+	
+	public interface
+	PluginSubscription
+	{
+		public String
+		getID();
+		
+		public String
+		getName();
+		
+		public PluginSubscriptionResult[]
+		getResults(
+			boolean		include_deleted );
+	}
+	
+	public interface
+	PluginSubscriptionResult
+	{
+		public Map<Integer,Object>
+		toPropertyMap();
+		
+		public void
+		setRead(
+			boolean		read );
+		
+		public boolean
+		getRead();
+	}
+	
 	public interface
 	runnableWithReturn<T>
 	{
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/Test.java b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/Test.java
index 710f540..d5bb341 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/Test.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/Test.java
@@ -47,7 +47,7 @@ Test
 		try{
 			ResourceDownloaderFactory	rdf = pi.getUtilities().getResourceDownloaderFactory();
 			
-			// ResourceDownloader rd_t = rdf.create(new URL("http://play.aelitis.com/torrents/Azureus2201-B22.jar.torrent"));
+			// ResourceDownloader rd_t = rdf.create(new URL("http://torrent.vuze.com:88/torrents/Azureus2201-B22.jar.torrent"));
 			
 			//rd_t = rdf.getMetaRefreshDownloader(rd_t);
 			
@@ -65,7 +65,7 @@ Test
 			
 			//rd_u = rdf.getSuffixBasedDownloader(rd_u);
 
-			ResourceDownloader rd_u = rdf.create( new URL( "http://torrents.aelitis.com:88/files/Azureus3009-B5.jar" ));
+			ResourceDownloader rd_u = rdf.create( new URL( "http://torrent.vuze.com:88/files/Azureus3009-B5.jar" ));
 			
 			// rd_u = rdf.getTorrentDownloader( rd_u, true );
 
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSChannelImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSChannelImpl.java
index b1a7959..1edfef8 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSChannelImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSChannelImpl.java
@@ -83,7 +83,28 @@ RSSChannelImpl
 	public String
 	getDescription()
 	{
-		return( node.getChild( is_atom?"summary":"description" ).getValue());
+		String[] fields;
+		
+		if ( is_atom ){
+			
+			fields = new String[]{ "summary", "description" };
+			
+		}else{
+			
+			fields = new String[]{ "description", "summary" };
+		}
+		
+		for ( String field: fields ){
+			
+			SimpleXMLParserDocumentNode x = node.getChild( field );
+			
+			if ( x != null ){
+				
+				return( x.getValue());
+			}
+		}
+		
+		return( null );
 	}
 	
 	public URL
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSItemImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSItemImpl.java
index d9f4d77..917760b 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSItemImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSItemImpl.java
@@ -28,6 +28,7 @@ import java.util.Date;
 
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.utils.xml.rss.RSSItem;
+import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentAttribute;
 import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentNode;
 
 /**
@@ -83,13 +84,34 @@ RSSItemImpl
 			try{
 				if ( is_atom ){
 					
-					return( new URL( link_node.getAttribute( "href" ).getValue()));
+					SimpleXMLParserDocumentAttribute attr = link_node.getAttribute( "href" );
+					
+					if ( attr == null ){
+						
+						return( null );
+					}
+					
+					String	value = attr.getValue().trim();
+					
+					if ( value.length() == 0 ){
+						
+						return( null );
+					}
+					
+					return( new URL( value ));
 
 				}else{
 				
-					return( new URL( link_node.getValue()));
+					String	value = link_node.getValue().trim();
+					
+					if ( value.length() == 0 ){
+						
+						return( null );
+					}
+					
+					return( new URL( value ));
 				}
-			}catch( MalformedURLException e ){
+			}catch( Throwable e ){
 			
 				Debug.printStackTrace(e);
 				
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/xml/simpleparser/SimpleXMLParserDocumentImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/xml/simpleparser/SimpleXMLParserDocumentImpl.java
index 31964d0..4c5e1e3 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/xml/simpleparser/SimpleXMLParserDocumentImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/xml/simpleparser/SimpleXMLParserDocumentImpl.java
@@ -37,9 +37,12 @@ public class
 SimpleXMLParserDocumentImpl
 	implements SimpleXMLParserDocument
 {
+	private static DocumentBuilderFactory 		dbf_singleton;
+
 	protected Document							document;
 	protected SimpleXMLParserDocumentNodeImpl	root_node;
 	
+	
 	public
 	SimpleXMLParserDocumentImpl(
 		File		file )
@@ -79,31 +82,31 @@ SimpleXMLParserDocumentImpl
 		create( input_stream );
 	}
 	
-	protected void
-	create(
-		InputStream		input_stream )
-		
-		throws SimpleXMLParserDocumentException
+	protected static synchronized DocumentBuilderFactory
+	getDBF()
 	{
-		try{
-			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+			// getting the factory involves a fait bit of work - cache it
+		
+		if ( dbf_singleton == null ){
+		
+			dbf_singleton = DocumentBuilderFactory.newInstance();
 
 			// Set namespaceAware to true to get a DOM Level 2 tree with nodes
 			// containing namesapce information.  This is necessary because the
 			// default value from JAXP 1.0 was defined to be false.
 						
-			dbf.setNamespaceAware(true);
-
+			dbf_singleton.setNamespaceAware(true);
+	
 			// Set the validation mode to either: no validation, DTD
 			// validation, or XSD validation
 					
-			dbf.setValidating( false );
+			dbf_singleton.setValidating( false );
 					
 			// Optional: set various configuration options
 					
-			dbf.setIgnoringComments(true);
-			dbf.setIgnoringElementContentWhitespace(true);
-			dbf.setCoalescing(true);
+			dbf_singleton.setIgnoringComments(true);
+			dbf_singleton.setIgnoringElementContentWhitespace(true);
+			dbf_singleton.setCoalescing(true);
 					
 			// The opposite of creating entity ref nodes is expanding them inline
 			// NOTE that usage of, e.g. "&amp;" in text results in an entity ref. e.g.
@@ -111,8 +114,20 @@ SimpleXMLParserDocumentImpl
 			//		ENT_REF: nodeName="amp"
 			//		TEXT: nodeName="#text" nodeValue="&"
 			
-			dbf.setExpandEntityReferences(true);
-					
+			dbf_singleton.setExpandEntityReferences(true);
+		}
+		
+		return( dbf_singleton );
+	}
+	
+	protected void
+	create(
+		InputStream		input_stream )
+		
+		throws SimpleXMLParserDocumentException
+	{
+		try{
+			DocumentBuilderFactory dbf = getDBF();
 
 			// Step 2: create a DocumentBuilder that satisfies the constraints
 			// specified by the DocumentBuilderFactory
diff --git a/org/gudy/azureus2/pluginsimpl/remote/download/RPDownload.java b/org/gudy/azureus2/pluginsimpl/remote/download/RPDownload.java
index c66b416..fd152fa 100644
--- a/org/gudy/azureus2/pluginsimpl/remote/download/RPDownload.java
+++ b/org/gudy/azureus2/pluginsimpl/remote/download/RPDownload.java
@@ -327,6 +327,14 @@ RPDownload
 		return( false );
 	}
 	
+	public long
+	getFlags()
+	{
+		notSupported();
+		
+		return( 0 );
+	}
+	
 	public int
 	getIndex()
 	{
diff --git a/org/gudy/azureus2/pluginsimpl/update/sf/impl2/SFPluginDetailsLoaderImpl.java b/org/gudy/azureus2/pluginsimpl/update/sf/impl2/SFPluginDetailsLoaderImpl.java
index 0af62fe..0aa95c0 100644
--- a/org/gudy/azureus2/pluginsimpl/update/sf/impl2/SFPluginDetailsLoaderImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/update/sf/impl2/SFPluginDetailsLoaderImpl.java
@@ -89,6 +89,8 @@ SFPluginDetailsLoaderImpl
 		try{
 			base_url_params += "&os=" + URLEncoder.encode(System.getProperty( "os.name"),"UTF-8" );
 			
+			base_url_params += "&osv=" + URLEncoder.encode(System.getProperty( "os.version" ),"UTF-8" );
+			
 			base_url_params += "&arch=" + URLEncoder.encode(System.getProperty( "os.arch"),"UTF-8" );
 			
 			base_url_params += "&ui=" + URLEncoder.encode(COConfigurationManager.getStringParameter("ui"),"UTF-8" );
diff --git a/org/gudy/azureus2/ui/icons/a128.jpg b/org/gudy/azureus2/ui/icons/a128.jpg
deleted file mode 100644
index 050a1f7..0000000
Binary files a/org/gudy/azureus2/ui/icons/a128.jpg and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/a128.png b/org/gudy/azureus2/ui/icons/a128.png
new file mode 100644
index 0000000..1d19b87
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/a128.png differ
diff --git a/org/gudy/azureus2/ui/icons/icons.properties b/org/gudy/azureus2/ui/icons/icons.properties
index b86375a..b476603 100644
--- a/org/gudy/azureus2/ui/icons/icons.properties
+++ b/org/gudy/azureus2/ui/icons/icons.properties
@@ -8,7 +8,6 @@ info=org/gudy/azureus2/ui/icons/info.gif
 progress_info=org/gudy/azureus2/ui/icons/progress_viewer_has_info.png
 search=org/gudy/azureus2/ui/icons/search.png
 cb_start=org/gudy/azureus2/ui/icons/toolbar/start.gif
-red_bubble=com/aelitis/azureus/ui/images/red_bubble.png
 st_shared=org/gudy/azureus2/ui/icons/status/shared.gif
 progress_viewer=org/gudy/azureus2/ui/icons/progress_viewer.png
 st_ok_shared=org/gudy/azureus2/ui/icons/status/ok_shared.gif
@@ -17,7 +16,6 @@ move=org/gudy/azureus2/ui/icons/move.gif
 edit_trackers=org/gudy/azureus2/ui/icons/edit_trackers.gif
 host=org/gudy/azureus2/ui/icons/host.gif
 st_ko=org/gudy/azureus2/ui/icons/status/ko.gif
-friend_online_icon=com/aelitis/azureus/ui/images/friend_online_icon.png
 cb_remove=org/gudy/azureus2/ui/icons/toolbar/remove.gif
 start=org/gudy/azureus2/ui/icons/start.gif
 cb_switch=org/gudy/azureus2/ui/icons/toolbar/switchui.png
@@ -27,17 +25,14 @@ spinner_big=multi,32,org/gudy/azureus2/ui/icons/spinning_indicator_big_white.png
 bottom=org/gudy/azureus2/ui/icons/bottom.gif
 cb_new=org/gudy/azureus2/ui/icons/toolbar/new.gif
 comment=org/gudy/azureus2/ui/icons/comment.png
-large_red_bubble=com/aelitis/azureus/ui/images/large_red_bubble.png
 greenled=org/gudy/azureus2/ui/icons/greenled.gif
 cb_stop=org/gudy/azureus2/ui/icons/toolbar/stop.gif
 run=org/gudy/azureus2/ui/icons/run.gif
-friends_bg=com/aelitis/azureus/ui/images/sb/friends_bg.png
 st_ko_shared=org/gudy/azureus2/ui/icons/status/ko_shared.gif
 sb_warning=org/gudy/azureus2/ui/icons/statusbar/status_warning.gif
 cb_top=org/gudy/azureus2/ui/icons/toolbar/top.gif
 popup=org/gudy/azureus2/ui/icons/popup.png
 delete=org/gudy/azureus2/ui/icons/delete.gif
-grey_bubble=com/aelitis/azureus/ui/images/grey_bubble.png
 cb_bottom=org/gudy/azureus2/ui/icons/toolbar/bottom.gif
 cb_open_folder=org/gudy/azureus2/ui/icons/toolbar/open_folder.gif
 cb_open_no_default=org/gudy/azureus2/ui/icons/toolbar/open_no_default.gif
@@ -53,9 +48,7 @@ azureus_splash=org/gudy/azureus2/ui/splash/splash_frog.jpg
 smallx=org/gudy/azureus2/ui/icons/smallx.png
 up=org/gudy/azureus2/ui/icons/up.png
 folder=org/gudy/azureus2/ui/icons/folder.gif
-btn_collapse_over=com/aelitis/azureus/ui/images/sb/icon_hide_notch_over.png
 yellowled=org/gudy/azureus2/ui/icons/yellowled.gif
-btn_expand_over=com/aelitis/azureus/ui/images/sb/icon_show_notch_over.png
 down=org/gudy/azureus2/ui/icons/down.png
 warning=org/gudy/azureus2/ui/icons/warning.gif
 dragger=org/gudy/azureus2/ui/icons/dragger.gif
@@ -65,7 +58,6 @@ no_comment=org/gudy/azureus2/ui/icons/comment_blank.png
 st_no_remote_shared=org/gudy/azureus2/ui/icons/status/no_remote_shared.gif
 downloadBar=org/gudy/azureus2/ui/icons/bar.gif
 sb_count=org/gudy/azureus2/ui/icons/statusbar/user_count.png
-btn_collapse=com/aelitis/azureus/ui/images/sb/icon_hide_notch.png
 st_stopped_shared=org/gudy/azureus2/ui/icons/status/stopped_shared.gif
 progress_retry=org/gudy/azureus2/ui/icons/progress_retry.png
 openFolderButton=org/gudy/azureus2/ui/icons/openFolder16x12.gif
@@ -81,7 +73,6 @@ cb_open_url=org/gudy/azureus2/ui/icons/toolbar/open_url.gif
 azureus64=org/gudy/azureus2/ui/icons/a64.png
 bbb_idle=org/gudy/azureus2/ui/icons/statusbar/bbb_idle.png
 recheck=org/gudy/azureus2/ui/icons/recheck.gif
-btn_expand=com/aelitis/azureus/ui/images/sb/icon_show_notch.png
 bbb_nli=org/gudy/azureus2/ui/icons/statusbar/bbb_notloggedin.png
 add_to_share_selected=com/aelitis/azureus/ui/images/buddy_add_to_share_selected.png
 details=org/gudy/azureus2/ui/icons/details.gif
@@ -94,9 +85,11 @@ speed=org/gudy/azureus2/ui/icons/speed.gif
 st_error=org/gudy/azureus2/ui/icons/status/error.gif
 lock=org/gudy/azureus2/ui/icons/lock.gif
 bbb_in=org/gudy/azureus2/ui/icons/statusbar/bbb_boosted.png
-azureus128=org/gudy/azureus2/ui/icons/a128.jpg
+azureus128=org/gudy/azureus2/ui/icons/a128.png
 azureus=org/gudy/azureus2/ui/icons/a16.png
 st_no_tracker_shared=org/gudy/azureus2/ui/icons/status/no_tracker_shared.gif
+pause=org/gudy/azureus2/ui/icons/pause.gif
+resume=org/gudy/azureus2/ui/icons/resume.gif
 
 azureus_white=org/gudy/azureus2/ui/icons/az3_osx_tray_white.png
 azureus_grey=org/gudy/azureus2/ui/icons/az3_osx_tray.png
diff --git a/org/gudy/azureus2/ui/icons/rcm.png b/org/gudy/azureus2/ui/icons/rcm.png
new file mode 100644
index 0000000..b18fa2f
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/rcm.png differ
diff --git a/org/gudy/azureus2/ui/jws/Main.java b/org/gudy/azureus2/ui/jws/Main.java
deleted file mode 100644
index 88de129..0000000
--- a/org/gudy/azureus2/ui/jws/Main.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * File    : Main.java
- * Created : 04-Feb-2004
- * By      : parg
- * 
- * Azureus - a Java Bittorrent client
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details ( see the LICENSE file ).
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-package org.gudy.azureus2.ui.jws;
-
-/**
- * @author parg
- *
- */
-
-import java.util.*;
-import java.net.*;
-
-import org.gudy.azureus2.plugins.*;
-import org.gudy.azureus2.plugins.logging.*;
-import org.gudy.azureus2.core3.util.*;
-
-import com.aelitis.azureus.launcher.Launcher;
-
-public class 
-Main 
-	implements Plugin, PluginListener, PluginEventListener
-{
-	protected static Main				singleton;
-	
-	protected static AESemaphore		init_sem = new AESemaphore("UIJWS");
-	private static AEMonitor			class_mon	= new AEMonitor( "UIJWS" );
-
-	public static Main
-	getSingleton(
-		final String[]	args )
-	{
-		try{
-			class_mon.enter();
-		
-			if ( singleton == null ){
-				
-				new AEThread( "plugin initialiser ")
-				{
-					public void
-					runSupport()
-					{
-						PluginManager.registerPlugin( Main.class );
-						
-						Properties props = new Properties();
-						
-						props.put( PluginManager.PR_MULTI_INSTANCE, "false" );
-											
-						PluginManager.startAzureus( PluginManager.UI_SWT, props );
-					}
-				}.start();
-				
-				init_sem.reserve();
-			}
-			
-			return( singleton );
-			
-		}finally{
-			
-			class_mon.exit();
-		}
-	}	
-	
-	protected PluginInterface		plugin_interface;
-	protected LoggerChannel 		log;
-	protected AESemaphore			ready_sem	= new AESemaphore("UIJWSReady");
-
-	public void 
-	initialize(
-		PluginInterface _pi )
-	{	
-		plugin_interface = _pi;
-
-		singleton	= this;
-		
-		log = plugin_interface.getLogger().getChannel("JWS Launcher");
-		
-		log.addListener(
-			new LoggerChannelListener()
-			{
-				public void
-				messageLogged(
-					int		type,
-					String	content )
-				{
-					System.out.println( content );
-				}
-				
-				public void
-				messageLogged(
-					String		str,
-					Throwable	error )
-				{
-					System.out.println( str );
-					
-					Debug.printStackTrace( error );
-				}
-			});
-		
-		log.log(LoggerChannel.LT_INFORMATION, "Plugin Initialised");
-		
-		plugin_interface.addListener( this );
-		
-		plugin_interface.addEventListener( this );
-		
-		init_sem.release();
-	}
-	
-	public void
-	initializationComplete()
-	{
-	}
-	
-	public void
-	handleEvent(
-		PluginEvent	ev )
-	{
-		System.out.println( "PluginEvent:" + ev.getType());
-		
-		if ( ev.getType() == PluginEvent.PEV_CONFIGURATION_WIZARD_COMPLETES ){
-			
-			ready_sem.release();
-		}
-	}
-	
-	protected void
-	process()
-	{
-		ready_sem.reserve();
-		
-		log.log(LoggerChannel.LT_INFORMATION, "processing jws request" );
-		
-		Properties props = System.getProperties();
-		
-		Enumeration enumx = props.keys();
-		
-		while( enumx.hasMoreElements()){
-		
-			String	key = (String)enumx.nextElement();
-			
-			log.log(LoggerChannel.LT_INFORMATION, "\t" + key + " = '" + props.get(key) + "'");
-		}
-		
-		String	torrent_url = (String)props.get( "azureus.javaws.torrent_url");
-		
-		log.log(LoggerChannel.LT_INFORMATION, "Torrent URL = " + torrent_url );
-		
-		if ( torrent_url != null ){
-			
-			try{
-				plugin_interface.getDownloadManager().addDownload(new URL(torrent_url));
-				
-			}catch( Throwable e ){
-							
-				log.log( e );
-			}
-		}
-		
-	}
-	
-	public void
-	closedownInitiated()
-	{
-	}
-	
-	public void
-	closedownComplete()
-	{
-	}
-	
-	public static void
-	main(
-		String[]		args )
-	{
-		if(Launcher.checkAndLaunch(Main.class, args))
-			return;
-		
-		getSingleton( args ).process();
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/CategoryAdderWindow.java b/org/gudy/azureus2/ui/swt/CategoryAdderWindow.java
index 1651c09..ce61317 100644
--- a/org/gudy/azureus2/ui/swt/CategoryAdderWindow.java
+++ b/org/gudy/azureus2/ui/swt/CategoryAdderWindow.java
@@ -20,122 +20,30 @@
  */
 package org.gudy.azureus2.ui.swt;
 
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.layout.RowData;
-import org.eclipse.swt.layout.RowLayout;
-import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.widgets.Display;
+
 import org.gudy.azureus2.core3.category.Category;
 import org.gudy.azureus2.core3.category.CategoryManager;
 import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.ui.swt.components.ControlUtils;
 
 /**
  * @author Olivier
  * 
  */
-public class CategoryAdderWindow {
-  private Category newCategory = null;
-  public CategoryAdderWindow(final Display display) {
-    final Shell shell = org.gudy.azureus2.ui.swt.components.shell.ShellFactory.createShell(display, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
-
-    shell.setText(MessageText.getString("CategoryAddWindow.title"));
-    Utils.setShellIcon(shell);
-    GridLayout layout = new GridLayout();
-    shell.setLayout(layout);
-
-    Label label = new Label(shell, SWT.NONE);
-    Messages.setLanguageText(label, "CategoryAddWindow.message");    
-    GridData gridData = new GridData();
-    gridData.widthHint = 200;
-    label.setLayoutData(gridData);
-
-    final Text category = new Text(shell, SWT.BORDER);
-    gridData = new GridData();
-    gridData.widthHint = 300;
-    category.setLayoutData(gridData);
-
-    Composite panel = new Composite(shell, SWT.NULL);
-    final RowLayout rLayout = new RowLayout();
-    rLayout.marginTop = 0;
-    rLayout.marginLeft = 0;
-    rLayout.marginBottom = 0;
-    rLayout.marginRight = 0;
-    try {
-    	rLayout.fill = true;
-    } catch (NoSuchFieldError e) {
-    	// SWT 2.x
-    }
-    rLayout.spacing = ControlUtils.getButtonMargin();
-    panel.setLayout(rLayout);
-    gridData = new GridData();
-    gridData.horizontalAlignment = (Constants.isOSX) ? SWT.END : SWT.CENTER;
-    panel.setLayoutData(gridData);
-
-    Button ok;
-    Button cancel;
-    if(Constants.isOSX) {
-        cancel = createAlertButton(panel, "Button.cancel");
-        ok = createAlertButton(panel, "Button.ok");
-    }
-    else {
-        ok = createAlertButton(panel, "Button.ok");
-        cancel = createAlertButton(panel, "Button.cancel");
-    }
-
-    ok.addListener(SWT.Selection, new Listener() {
-      /* (non-Javadoc)
-       * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
-       */
-      public void handleEvent(Event event) {
-        try {
-          if (category.getText() != "") {
-           newCategory = CategoryManager.createCategory(category.getText());
-          }
-        	
-        	shell.dispose();
-        }
-        catch (Exception e) {
-        	Debug.printStackTrace( e );
-        }
-      }
-    });
-    cancel.addListener(SWT.Selection, new Listener() {
-      /* (non-Javadoc)
-       * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
-       */
-      public void handleEvent(Event event) {
-        shell.dispose();
-      }
-    });
-
-    shell.setDefaultButton(ok);
-
-    shell.pack();
-    Utils.createURLDropTarget(shell, category);
-    Utils.centreWindow(shell);
-    shell.open();
-    while (!shell.isDisposed())
-      if (!display.readAndDispatch()) display.sleep();
-  }
-
-  private static Button createAlertButton(final Composite panel, String localizationKey)
-  {
-      final Button button = new Button(panel, SWT.PUSH);
-      button.setText(MessageText.getString(localizationKey));
-      final RowData rData = new RowData();
-      rData.width = Math.max(
-              ControlUtils.getDialogButtonMinWidth(),
-              button.computeSize(SWT.DEFAULT,  SWT.DEFAULT).x
-        );
-      button.setLayoutData(rData);
-      return button;
-  }
-
-  public Category getNewCategory() {
-    return newCategory;
-  }
+public class CategoryAdderWindow
+{
+	private Category newCategory;
+
+	public CategoryAdderWindow(final Display display) {
+		SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
+				"CategoryAddWindow.title", "CategoryAddWindow.message");
+		entryWindow.prompt();
+		if (entryWindow.hasSubmittedInput()) {
+			newCategory = CategoryManager.createCategory(entryWindow.getSubmittedInput());
+		}
+	}
+
+	public Category getNewCategory() {
+		return newCategory;
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/IconBar.java b/org/gudy/azureus2/ui/swt/IconBar.java
index 42f77f8..cdc7225 100644
--- a/org/gudy/azureus2/ui/swt/IconBar.java
+++ b/org/gudy/azureus2/ui/swt/IconBar.java
@@ -30,14 +30,10 @@ import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.components.BufferedToolItem;
-import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
-import com.aelitis.azureus.ui.UIFunctions;
-import com.aelitis.azureus.ui.UIFunctionsManager;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
 /**
@@ -108,23 +104,7 @@ public class IconBar {
 			Messages.setLanguageText(tiSwitch, "iconBar.switch.tooltip", true);
 			tiSwitch.addSelectionListener(new SelectionListener() {
 				public void widgetSelected(SelectionEvent e) {
-					String uiOld = COConfigurationManager.getStringParameter("ui");
-					String uiNew = UISwitcherUtil.openSwitcherWindow(true);
-					if (!uiOld.equals(uiNew) && !IconBar.this.parent.isDisposed()) {
-  					int result = MessageBoxShell.open(IconBar.this.parent.getShell(),
-  							MessageText.getString("dialog.uiswitcher.restart.title"),
-  							MessageText.getString("dialog.uiswitcher.restart.text"),
-  							new String[] {
-  								MessageText.getString("UpdateWindow.restart"),
-  								MessageText.getString("UpdateWindow.restartLater"),
-  							}, 0);
-  					if (result == 0) {
-    					UIFunctions uif = UIFunctionsManager.getUIFunctions();
-    					if (uif != null) {
-    						uif.dispose(true, false);
-    					}
-  					}
-					}
+					UISwitcherUtil.openSwitcherWindow();
 				}
 
 				public void widgetDefaultSelected(SelectionEvent e) {
diff --git a/org/gudy/azureus2/ui/swt/ImageRepository.java b/org/gudy/azureus2/ui/swt/ImageRepository.java
index fa47829..3459089 100644
--- a/org/gudy/azureus2/ui/swt/ImageRepository.java
+++ b/org/gudy/azureus2/ui/swt/ImageRepository.java
@@ -53,7 +53,7 @@ public class ImageRepository
 		".exe"
 	};
 
-	private static final boolean forceNoAWT = Constants.isOSX;
+	private static final boolean forceNoAWT = Constants.isOSX || Constants.isWindows;
 
 	/**public*/
 	static void addPath(String path, String id) {
@@ -75,7 +75,7 @@ public class ImageRepository
 	   *
 	   * @param program the Program
 	   */
-	public static Image getIconFromExtension(String ext, boolean bBig,
+	public static Image getIconFromExtension(File file, String ext, boolean bBig,
 			boolean minifolder) {
 		Image image = null;
 
@@ -97,19 +97,54 @@ public class ImageRepository
 
 			ImageData imageData = null;
 
-			if (Constants.isWindows && bBig) {
+			if (Constants.isWindows) {
 				try {
-					Class ehancerClass = Class.forName("org.gudy.azureus2.ui.swt.win32.Win32UIEnhancer");
-					Method method = ehancerClass.getMethod("getBigImageData",
+					//Image icon = Win32UIEnhancer.getFileIcon(new File(path), big);
+					
+					Class<?> enhancerClass = Class.forName("org.gudy.azureus2.ui.swt.win32.Win32UIEnhancer");
+					Method method = enhancerClass.getMethod("getFileIcon",
 							new Class[] {
-								String.class
+								File.class,
+								boolean.class
 							});
-					imageData = (ImageData) method.invoke(null, new Object[] {
-						ext
+					image = (Image) method.invoke(null, new Object[] {
+						file,
+						bBig
 					});
+					if (image != null) {
+						if (!bBig)
+							image = force16height(image);
+						if (minifolder)
+							image = minifolderize(file.getParent(), image, bBig);
+						ImageLoader.getInstance().addImageNoDipose(key, image);
+						return image;
+					}
 				} catch (Exception e) {
 					Debug.printStackTrace(e);
 				}
+			} else if (Utils.isCocoa) {
+				try {
+					Class<?> enhancerClass = Class.forName("org.gudy.azureus2.ui.swt.osx.CocoaUIEnhancer");
+					Method method = enhancerClass.getMethod("getFileIcon",
+							new Class[] {
+								String.class,
+								int.class
+							});
+					image = (Image) method.invoke(null, new Object[] {
+						file.getAbsolutePath(),
+						(int) (bBig ? 128 : 16)
+					});
+					if (image != null) {
+						if (!bBig)
+							image = force16height(image);
+						if (minifolder)
+							image = minifolderize(file.getParent(), image, bBig);
+						ImageLoader.getInstance().addImageNoDipose(key, image);
+						return image;
+					}
+				} catch (Throwable t) {
+					Debug.printStackTrace(t);
+				}
 			}
 
 			if (imageData == null) {
@@ -124,7 +159,7 @@ public class ImageRepository
 				if (!bBig)
 					image = force16height(image);
 				if (minifolder)
-					image = minifolderize(image, bBig);
+					image = minifolderize(file.getParent(), image, bBig);
 
 				ImageLoader.getInstance().addImageNoDipose(key, image);
 			}
@@ -139,8 +174,8 @@ public class ImageRepository
 		return image;
 	}
 
-	private static Image minifolderize(Image img, boolean big) {
-		Image imgFolder = getImage(big ? "folder" : "foldersmall");
+	private static Image minifolderize(String path, Image img, boolean big) {
+		Image imgFolder =  getImage(big ? "folder" : "foldersmall");
 		Rectangle folderBounds = imgFolder.getBounds();
 		Rectangle dstBounds = img.getBounds();
 		Image tempImg = Utils.renderTransparency(Display.getCurrent(), img,
@@ -181,7 +216,7 @@ public class ImageRepository
 	}
 
 	/**
-	* <p>Gets a small-sized iconic representation of the file or directory at the path</p>
+	* <p>Gets an iconic representation of the file or directory at the path</p>
 	* <p>For most platforms, the icon is a 16x16 image; weak-referencing caching is used to avoid abundant reallocation.</p>
 	* @param path Absolute path to the file or directory
 	* @return The image
@@ -206,6 +241,9 @@ public class ImageRepository
 			String key;
 			if (file.isDirectory()) {
 				if (noAWT) {
+					if (Constants.isWindows || Utils.isCocoa) {
+						return getIconFromExtension(file, "-folder", bBig, false);
+					}
 					return getImage("folder");
 				}
 
@@ -224,7 +262,7 @@ public class ImageRepository
 					key = ext;
 					
 					if (noAWT)
-						return getIconFromExtension(ext, bBig, minifolder);
+						return getIconFromExtension(file, ext, bBig, minifolder);
 
 					// case-insensitive file systems
 					for (int i = 0; i < noCacheExtList.length; i++) {
@@ -296,7 +334,7 @@ public class ImageRepository
 					image = force16height(image);
 				}
 				if (minifolder)
-					image = minifolderize(image, bBig);
+					image = minifolderize(file.getParent(), image, bBig);
 
 				
 				ImageLoader.getInstance().addImageNoDipose(key, image);
@@ -320,7 +358,7 @@ public class ImageRepository
 			return getImage("folder");
 		}
 
-		return getIconFromExtension(ext, bBig, minifolder);
+		return getIconFromExtension(file, ext, bBig, minifolder);
 	}
 
 	public static void main(String[] args) {
diff --git a/org/gudy/azureus2/ui/swt/MessageBoxWindow.java b/org/gudy/azureus2/ui/swt/MessageBoxWindow.java
deleted file mode 100644
index 81e2a03..0000000
--- a/org/gudy/azureus2/ui/swt/MessageBoxWindow.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Created on 02-Oct-2005
- * Created by Paul Gardner
- * Copyright (C) 2005, 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- * 
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-
-package org.gudy.azureus2.ui.swt;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.AESemaphore;
-import org.gudy.azureus2.ui.swt.components.BufferedLabel;
-
-import com.aelitis.azureus.ui.common.RememberedDecisionsManager;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-
-
-
-public class 
-MessageBoxWindow 
-{
-	public static final String ICON_ERROR 		= "error";
-	public static final String ICON_WARNING 	= "warning";
-	public static final String ICON_INFO	 	= "info";
-
-	public static int 
-	open(
-		String	id,
-		int		options,
-		int		remember_map,
-		boolean	default_is_yes,
-		Display display,
-		String	icon,
-		String	title,
-		String	message ) 
-	{
-		int remembered = RememberedDecisionsManager.getRememberedDecision(id,
-				remember_map);
-		
-		if ( remembered > 0 ){
-			
-			return( remembered );
-		}
-		
-		return( new MessageBoxWindow( id, options, remember_map != SWT.NULL, default_is_yes, display, icon, title, message ).getResult());
-	}
-  
-	private Shell shell;
-	
-	private AESemaphore	result_sem = new AESemaphore( "MessageBoxWindow" );
-	
-	private volatile int			result;
-	private volatile boolean		result_set;
-	
-	protected 
-	MessageBoxWindow(
-		final String	id,
-		final int		options,
-		final boolean	remember_decision,
-		final boolean	default_is_yes,
-		final Display 	display,
-		final String	icon,
-		final String	title,
-		final String	message )
-	{	
-		shell = new Shell(display,SWT.APPLICATION_MODAL | SWT.TITLE | SWT.CLOSE );
-
-		shell.setText( title );
-		
-		Utils.setShellIcon(shell);
-		
-	    GridLayout layout = new GridLayout();
-	    layout.numColumns = 3;
-	    shell.setLayout(layout);
-	    
-	    	// image and text
-	    
-	    Label label = new Label(shell,SWT.NONE);
-
-	    ImageLoader.getInstance().setLabelImage(label, icon);
-	    
-	    	// buffered label handles & in the text properly
-	    
-	    BufferedLabel	msg_label = new BufferedLabel(shell,SWT.WRAP);
-	    msg_label.setText(message);
-	    GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
-	    gridData.horizontalSpan = 2;
-	    msg_label.setLayoutData(gridData);
-	    
-	    	// remember decision
-	    
-	    final Button checkBox;
-	    
-	    if ( remember_decision ){
-	    	
-		    checkBox = new Button(shell, SWT.CHECK);
-		    checkBox.setSelection(false);
-		    checkBox.setText( MessageText.getString( "MessageBoxWindow.rememberdecision" ));
-			gridData = new GridData(GridData.FILL_HORIZONTAL);
-			gridData.horizontalSpan = 3;
-			checkBox.setLayoutData(gridData);
-	    }else{
-	    	checkBox = null;
-	    	Label	pad = new Label( shell, SWT.NULL );
-			gridData = new GridData(GridData.FILL_HORIZONTAL);
-			gridData.horizontalSpan = 3;
-			pad.setLayoutData(gridData);
-	    }
-
-	    
-			// line
-		
-		Label labelSeparator = new Label(shell,SWT.SEPARATOR | SWT.HORIZONTAL);
-		gridData = new GridData(GridData.FILL_HORIZONTAL);
-		gridData.horizontalSpan = 3;
-		labelSeparator.setLayoutData(gridData);
-
-			// buttons
-			
-		label = new Label(shell,SWT.NULL);
-
-		final int yes_option = options & ( SWT.OK | SWT.YES );
-		
-		Button bYes = new Button(shell,SWT.PUSH);
-	 	bYes.setText(MessageText.getString( yes_option==SWT.YES?"Button.yes":"Button.ok"));
-	 	gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_END | GridData.HORIZONTAL_ALIGN_FILL);
-	 	gridData.grabExcessHorizontalSpace = true;
-	 	gridData.widthHint = 70;
-	 	bYes.setLayoutData(gridData);
-	 	bYes.addListener(SWT.Selection,new Listener() {
-	  		public void handleEvent(Event e) {
-	  			setResult( id, yes_option, checkBox==null?false:checkBox.getSelection());
-	   		}
-		 });
-    
-		final int no_option = options & ( SWT.CANCEL | SWT.NO );
-
-	 	Button bNo = new Button(shell,SWT.PUSH);
-	 	bNo.setText(MessageText.getString(no_option==SWT.NO?"Button.no":"Button.cancel"));
-	 	gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
-	 	gridData.grabExcessHorizontalSpace = false;
-	 	gridData.widthHint = 70;
-	 	bNo.setLayoutData(gridData);    
-	 	bNo.addListener(SWT.Selection,new Listener() {
-	 		public void handleEvent(Event e) {
-	 			setResult( id, no_option, checkBox==null?false:checkBox.getSelection());
-	   		}
-	 	});
-	 	
-		shell.setDefaultButton( default_is_yes?bYes:bNo );
-		
-		shell.addListener(SWT.Traverse, new Listener() {	
-			public void handleEvent(Event e) {
-				if ( e.character == SWT.ESC){
-					setResult( id, SWT.NULL, false );
-				}
-			}
-		});
-    
-	    shell.addListener(
-	    	SWT.Close,
-	    	new Listener() 
-	    	{
-	    		public void 
-	    		handleEvent(
-	    			Event arg0) 
-	    		{
-	    			setResult( id, SWT.NULL, false );
-	    		}
-	    	});
-    
-		
-	 	shell.pack ();
-	 	
-		Utils.centreWindow( shell );
-        
-	    shell.open();
-	    
-	    (default_is_yes?bYes:bNo).setFocus();
-	    
-	    while( !shell.isDisposed()) {
-	       
-	    	if (!display.readAndDispatch()){
-	    		
-	              display.sleep();
-	        }
-	    }
-	}      
-
-	protected void
-	setResult(
-		String		id,
-		int			option,
-		boolean		remember )
-	{
-		if ( !result_set ){
-			
-			result	= option;
-			
-			result_set	= true;
-			
-			if ( remember ){
-				
-				RememberedDecisionsManager.setRemembered(id, result);
-			}
-			
-			result_sem.release();
-			
-			close();
-		}
-	}
-	
-	protected void
-	close()
-	{
-		if ( !shell.isDisposed()){
-			
-			shell.dispose();
-		}
-	}
-	
-	protected int
-	getResult()
-	{
-		result_sem.reserve();
-		
-		return( result );
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/Messages.java b/org/gudy/azureus2/ui/swt/Messages.java
index 3d46d04..b27da7e 100644
--- a/org/gudy/azureus2/ui/swt/Messages.java
+++ b/org/gudy/azureus2/ui/swt/Messages.java
@@ -97,13 +97,10 @@ public class Messages {
         
         // XXX We could (should?) send this event for all widget types
         // XXX Would it better to have a custom event type?
-        if (SWT.getVersion() > 3200) {
-	        Event event = new Event();
-	    		// SWT 3.2 only.  Code Ok -- Only called in SWT 3.2 mode
-	        event.type = SWT.Settings;
-	        event.widget = widget;
-	        widget.notifyListeners(SWT.Settings, event);
-        }
+        Event event = new Event();
+        event.type = SWT.Settings;
+        event.widget = widget;
+        widget.notifyListeners(SWT.Settings, event);
       }
       else if (widget instanceof Tree) {
         Tree tree = (Tree) widget;
diff --git a/org/gudy/azureus2/ui/swt/OpenTorrentWindow.java b/org/gudy/azureus2/ui/swt/OpenTorrentWindow.java
index cc4ca70..80b684f 100644
--- a/org/gudy/azureus2/ui/swt/OpenTorrentWindow.java
+++ b/org/gudy/azureus2/ui/swt/OpenTorrentWindow.java
@@ -62,11 +62,11 @@ import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.shells.MessageSlideShell;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.ui.UIFunctionsManager;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT;
@@ -237,7 +237,7 @@ public class OpenTorrentWindow
 			OpenTorrentWindow openTorrentWindow = stOpenTorrentWindow;
 			openTorrentWindow.bOverrideStartModeToStopped = bDefaultStopped;
 			openTorrentWindow.bDefaultForSeeding = bForSeeding;
-			if (sFilesToOpen != null) {
+			if (sFilesToOpen != null || sPathOfFilesToOpen != null) {
 				// If none of the files sent to us were valid files, don't open the 
 				// window
 				if (!bPopupOpenURL
@@ -500,31 +500,12 @@ public class OpenTorrentWindow
 
 		cmbDataDir.addModifyListener(new ModifyListener() {
 			public void modifyText(ModifyEvent e) {
-				if (bSkipDataDirModify) {
-					return;
-				}
-				sDestDir = cmbDataDir.getText();
-
-				int[] indexes = torrentTable.getSelectionIndices();
-				for (int i = 0; i < indexes.length; i++) {
-					TorrentInfo info = (TorrentInfo) torrentList.get(indexes[i]);
-					//if (!info.allFilesMoving())
-					info.sDestDir = sDestDir;
-				}
-
-				torrentTable.clearAll();
-
-				checkSeedingMode();
-
-				File file = new File(sDestDir);
-				if (!file.isDirectory()) {
-					cmbDataDir.setBackground(Colors.colorErrorBG);
-				} else {
-					cmbDataDir.setBackground(null);
-				}
-				cmbDataDir.redraw();
-				cmbDataDir.update();
-				diskFreeInfoRefreshPending = true;
+				cmbDataDirChanged();
+			}
+		});
+		cmbDataDir.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				cmbDataDirChanged();
 			}
 		});
 
@@ -681,6 +662,36 @@ public class OpenTorrentWindow
 		}
 	}
 
+	protected void cmbDataDirChanged() {
+		if (bSkipDataDirModify) {
+			return;
+		}
+		sDestDir = cmbDataDir.getText();
+
+		int[] indexes = torrentTable.getSelectionIndices();
+		for (int i = 0; i < indexes.length; i++) {
+			TorrentInfo info = (TorrentInfo) torrentList.get(indexes[i]);
+			//if (!info.allFilesMoving())
+			info.sDestDir = sDestDir;
+		}
+
+		torrentTable.clearAll();
+
+		checkSeedingMode();
+
+		if (!Utils.isCocoa || SWT.getVersion() > 3600) { // See Eclipse Bug 292449
+  		File file = new File(sDestDir);
+  		if (!file.isDirectory()) {
+  			cmbDataDir.setBackground(Colors.colorErrorBG);
+  		} else {
+  			cmbDataDir.setBackground(null);
+  		}
+  		cmbDataDir.redraw();
+  		cmbDataDir.update();
+		}
+		diskFreeInfoRefreshPending = true;
+	}
+
 	protected void okPressed() {
 		if (bClosed) {
 			return;
@@ -702,11 +713,13 @@ public class OpenTorrentWindow
 
 		boolean isPathInvalid = cmbDataDir.getText().length() == 0 || file.isFile();
 		if (!isPathInvalid && !file.isDirectory()) {
-			int doCreate = Utils.openMessageBox(shellForChildren, SWT.YES | SWT.NO
+			MessageBoxShell mb = new MessageBoxShell(SWT.YES | SWT.NO
 					| SWT.ICON_QUESTION, "OpenTorrentWindow.mb.askCreateDir",
 					new String[] {
 						file.toString()
 					});
+			mb.open(null);
+			int doCreate = mb.waitUntilClosed();
 
 			if (doCreate == SWT.YES)
 				isPathInvalid = !FileUtil.mkdirs(file);
@@ -717,10 +730,11 @@ public class OpenTorrentWindow
 		}
 
 		if (isPathInvalid) {
-			Utils.openMessageBox(shellForChildren, SWT.OK | SWT.ICON_ERROR,
+			MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.ICON_ERROR,
 					"OpenTorrentWindow.mb.noGlobalDestDir", new String[] {
 						file.toString()
 					});
+			mb.open(null);
 			cmbDataDir.setFocus();
 			return;
 		}
@@ -740,19 +754,21 @@ public class OpenTorrentWindow
 			// 4) change the global def directory to a real one
 			// 5) click ok.  "hi.exe" will be written as moo in c:\test			
 			if (!file.isDirectory() && !FileUtil.mkdirs(file)) {
-				Utils.openMessageBox(shellForChildren, SWT.OK | SWT.ICON_ERROR,
+				MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.ICON_ERROR,
 						"OpenTorrentWindow.mb.noDestDir", new String[] {
 							file.toString(),
 							info.getTorrentName()
 						});
+				mb.open(null);
 				return;
 			}
 
 			if (!info.isValid) {
-				Utils.openMessageBox(shellForChildren, SWT.OK | SWT.ICON_ERROR,
+				MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.ICON_ERROR,
 						"OpenTorrentWindow.mb.notValid", new String[] {
 							info.getTorrentName()
 						});
+				mb.open(null);
 				return;
 			}
 
@@ -781,11 +797,13 @@ public class OpenTorrentWindow
 						+ "\n";
 			}
 
-			if (Utils.openMessageBox(shellForChildren, SWT.OK | SWT.CANCEL
+			MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.CANCEL
 					| SWT.ICON_WARNING, "OpenTorrentWindow.mb.existingFiles",
 					new String[] {
 						sExistingFiles
-					}) != SWT.OK) {
+					});
+			mb.open(null);
+			if (mb.waitUntilClosed() != SWT.OK) {
 				return;
 			}
 		}
@@ -1150,7 +1168,7 @@ public class OpenTorrentWindow
 		// Menu for tableTorrents
 
 		String sTitle;
-		Menu menu = new Menu(torrentTable);
+		Menu menu = new Menu(torrentTable.getShell());
 		MenuItem item;
 		sTitle = MessageText.getString("OpenTorrentWindow.startMode");
 
@@ -1221,7 +1239,7 @@ public class OpenTorrentWindow
 					TorrentInfo info = (TorrentInfo) torrentList.get(indexes[i]);
 
 					TorrentFileInfo[] files = info.getFiles();
-					if (files.length == 1) {
+					if (files.length == 1 && info.torrent.isSimpleTorrent()) {
 						changeFileDestination(new int[] {
 							0
 						});
@@ -1779,12 +1797,14 @@ public class OpenTorrentWindow
 				File file = new File(sNewName);
 				if (file.length() == fileInfo.lSize)
 					fileInfo.setFullDestName(sNewName);
-				else
-					Utils.openMessageBox(shellForChildren, SWT.OK,
+				else {
+					MessageBoxShell mb = new MessageBoxShell(SWT.OK,
 							"OpenTorrentWindow.mb.badSize", new String[] {
 								file.getName(),
 								fileInfo.orgFullName
 							});
+					mb.open(null);
+				}
 			} else
 				fileInfo.setFullDestName(sNewName);
 
@@ -1977,23 +1997,25 @@ public class OpenTorrentWindow
 				sFileName = UrlUtils.decode(sFileName.substring(16));
 			}
 
-			File fOriginal = new File(sFileName);
+			final File fOriginal = new File(sFileName);
 
 			if (!fOriginal.isFile() || !fOriginal.exists()) {
 				Utils.execSWTThread(new AERunnable() {
 					public void runSupport() {
 						if (shell == null)
 							new MessageSlideShell(Display.getCurrent(), SWT.ICON_ERROR,
-									"OpenTorrentWindow.mb.openError", "", new String[] {
-										sOriginatingLocation,
+									"OpenTorrentWindow.mb.openError", fOriginal.toString(), new String[] {
+										UrlUtils.decode(sOriginatingLocation),
 										"Not a File"
 									}, -1 );
-						else
-							Utils.openMessageBox(shell, SWT.OK,
+						else {
+							MessageBoxShell mb = new MessageBoxShell(SWT.OK,
 									"OpenTorrentWindow.mb.openError", new String[] {
 										sOriginatingLocation,
 										"Not a File"
 									});
+							mb.open(null);
+						}
 					}
 				});
 				return null;
@@ -2033,12 +2055,14 @@ public class OpenTorrentWindow
 									sOriginatingLocation,
 									e.getMessage()
 								}, -1 );
-					else
-						Utils.openMessageBox(shell, SWT.OK,
+					else {
+						MessageBoxShell mb = new MessageBoxShell(SWT.OK,
 								"OpenTorrentWindow.mb.openError", new String[] {
 									sOriginatingLocation,
 									e.getMessage()
 								});
+						mb.open(null);
+					}
 				}
 			});
 
@@ -2101,13 +2125,15 @@ public class OpenTorrentWindow
 								}, new Object[] {
 									fExistingDownload
 								}, -1 );
-					else
-						Utils.openMessageBox(shell, SWT.OK, MSG_ALREADY_EXISTS,
+					else {
+						MessageBoxShell mb = new MessageBoxShell(SWT.OK, MSG_ALREADY_EXISTS,
 								new String[] {
 									":" + sOriginatingLocation,
 									sfExistingName,
 									MessageText.getString(MSG_ALREADY_EXISTS_NAME),
 								});
+						mb.open(null);
+					}
 				}
 			});
 
@@ -2180,6 +2206,14 @@ public class OpenTorrentWindow
 	 * @param sDataDir 
 	 */
 	private void openTorrents() {
+		Utils.getOffOfSWTThread(new AERunnable() {
+			public void runSupport() {
+				_openTorrents();
+			}
+		});
+	}
+
+	private void _openTorrents() {
 		ArrayList addedTorrentsTop = new ArrayList();
 
 		for (int i = 0; i < torrentList.size(); i++) {
@@ -2215,12 +2249,17 @@ public class OpenTorrentWindow
 								DiskManagerFileInfo fileInfo = fileInfos[iIndex];
 								if (iIndex >= 0 && iIndex < files.length && files[iIndex].lSize == fileInfo.getLength())
 								{
-									File fDest = files[iIndex].getDestFileFullName();
+									// Always pull destination file from fileInfo and not from
+									// TorrentFileInfo because the destination may have changed
+									// by magic code elsewhere
+									File fDest = fileInfo.getFile(true);
 									if (files[iIndex].isLinked())
 									{
+										fDest = files[iIndex].getDestFileFullName();
 										// Can't use fileInfo.setLink(fDest) as it renames
 										// the existing file if there is one
-										dm.getDownloadState().setFileLink(fileInfo.getFile(false), fDest);
+										dm.getDownloadState().setFileLink(
+														fileInfo.getFile(false), fDest);
 									}
 									if (!files[iIndex].bDownload)
 									{
@@ -2262,12 +2301,14 @@ public class OpenTorrentWindow
 								info.sOriginatingLocation,
 								e.getMessage()
 							}, -1 );
-				else
-					Utils.openMessageBox(shell, SWT.OK, "OpenTorrentWindow.mb.openError",
+				else {
+					MessageBoxShell mb = new MessageBoxShell(SWT.OK, "OpenTorrentWindow.mb.openError",
 							new String[] {
 								info.sOriginatingLocation,
 								e.getMessage()
 							});
+					mb.open(null);
+				}
 			}
 		}
 
diff --git a/org/gudy/azureus2/ui/swt/PasswordWindow.java b/org/gudy/azureus2/ui/swt/PasswordWindow.java
index 731b279..a45885e 100644
--- a/org/gudy/azureus2/ui/swt/PasswordWindow.java
+++ b/org/gudy/azureus2/ui/swt/PasswordWindow.java
@@ -32,6 +32,7 @@ import org.eclipse.swt.widgets.*;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
@@ -86,7 +87,7 @@ public class PasswordWindow {
   protected PasswordWindow(Display display) {
   	bOk = false;
 
-    shell = new Shell(display,SWT.APPLICATION_MODAL | SWT.TITLE | SWT.CLOSE);
+    shell = ShellFactory.createMainShell(SWT.APPLICATION_MODAL | SWT.TITLE | SWT.CLOSE);
     shell.setText(MessageText.getString("PasswordWindow.title"));
     Utils.setShellIcon(shell);
     GridLayout layout = new GridLayout();
diff --git a/org/gudy/azureus2/ui/swt/PropertiesWindow.java b/org/gudy/azureus2/ui/swt/PropertiesWindow.java
index ead2602..af6825a 100644
--- a/org/gudy/azureus2/ui/swt/PropertiesWindow.java
+++ b/org/gudy/azureus2/ui/swt/PropertiesWindow.java
@@ -33,6 +33,7 @@ import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.ui.swt.components.BufferedLabel;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 
 
 public class 
@@ -46,9 +47,7 @@ PropertiesWindow
 		String[]	keys,
 		String[]	values )
 	{	
-		final Shell any_shell = Utils.findAnyShell();
-
-		shell = new Shell( any_shell.getDisplay(),SWT.APPLICATION_MODAL | SWT.TITLE | SWT.CLOSE |SWT.RESIZE );
+		shell = ShellFactory.createMainShell(SWT.APPLICATION_MODAL | SWT.TITLE | SWT.CLOSE |SWT.RESIZE );
 
 		shell.setText( MessageText.getString( "props.window.title", new String[]{ object_name }));
 		
diff --git a/org/gudy/azureus2/ui/swt/SimpleTextEntryWindow.java b/org/gudy/azureus2/ui/swt/SimpleTextEntryWindow.java
index aa28189..112bfb7 100644
--- a/org/gudy/azureus2/ui/swt/SimpleTextEntryWindow.java
+++ b/org/gudy/azureus2/ui/swt/SimpleTextEntryWindow.java
@@ -23,18 +23,15 @@ package org.gudy.azureus2.ui.swt;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.TraverseEvent;
 import org.eclipse.swt.events.TraverseListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.layout.RowData;
-import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
+
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.ui.UIInputValidator;
 import org.gudy.azureus2.ui.swt.components.ControlUtils;
 import org.gudy.azureus2.ui.swt.pluginsimpl.AbstractUISWTInputReceiver;
-import org.eclipse.swt.widgets.MessageBox;
 
 /**
  * @author amc1
@@ -43,6 +40,7 @@ import org.eclipse.swt.widgets.MessageBox;
 public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 	
 	private Display display;
+	private Shell shell;
 	
 	public SimpleTextEntryWindow() {
 	}
@@ -66,12 +64,24 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 	
 	protected void promptForInput() {
 		Utils.execSWTThread(new Runnable() {
-			public void run() {promptForInput0();}
-		}, false);
+			public void run() {
+				promptForInput0();
+				if (receiver_listener == null) {
+					while (shell != null && !shell.isDisposed())
+						if (!display.readAndDispatch()) display.sleep();
+				}
+			}
+		}, receiver_listener != null);
 	}
 	
 	private void promptForInput0() {
-		final Shell shell = org.gudy.azureus2.ui.swt.components.shell.ShellFactory.createShell(Utils.findAnyShell(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+		//shell = org.gudy.azureus2.ui.swt.components.shell.ShellFactory.createShell(Utils.findAnyShell(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+		// link to active shell, so that when it closes, the input box closes (good for config windows)
+		Shell parent = Display.getDefault().getActiveShell();
+		if (parent == null) {
+			parent = Utils.findAnyShell();
+		}
+		shell = org.gudy.azureus2.ui.swt.components.shell.ShellFactory.createShell(parent, SWT.DIALOG_TRIM);
 
 		display = shell.getDisplay();
 		if (this.title != null) {
@@ -90,7 +100,7 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 	    Label label = null;
 	    GridData gridData = null;
 	    for (int i=0; i<this.messages.length; i++) {
-	    	label = new Label(shell, SWT.NONE);
+	    	label = new Label(shell, SWT.WRAP);
 	    	label.setText(this.messages[i]);
 	    	
 	    	// 330 is the current default width.
@@ -259,13 +269,17 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 			}
 		});
 		
+		shell.addListener(SWT.Dispose, new Listener() {
+			public void handleEvent(Event event) {
+				triggerReceiverListener();
+			}
+		});
+		
 	    shell.pack();
 	    if (text_entry_text != null)
 	    	Utils.createURLDropTarget(shell, text_entry_text);
 	    Utils.centreWindow(shell);
 	    shell.open();
-	    while (!shell.isDisposed())
-	      if (!display.readAndDispatch()) display.sleep();
 	  }
 
   private static Button createAlertButton(final Composite panel, String localizationKey)
diff --git a/org/gudy/azureus2/ui/swt/TorrentUtil.java b/org/gudy/azureus2/ui/swt/TorrentUtil.java
index 5dc22ab..ebc506d 100644
--- a/org/gudy/azureus2/ui/swt/TorrentUtil.java
+++ b/org/gudy/azureus2/ui/swt/TorrentUtil.java
@@ -35,7 +35,6 @@ import org.eclipse.swt.widgets.*;
 import org.gudy.azureus2.core3.category.Category;
 import org.gudy.azureus2.core3.category.CategoryManager;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerState;
 import org.gudy.azureus2.core3.internat.MessageText;
@@ -43,22 +42,31 @@ import org.gudy.azureus2.core3.logging.LogAlert;
 import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
 import org.gudy.azureus2.core3.peer.PEPeerSource;
-import org.gudy.azureus2.core3.torrent.*;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
 import org.gudy.azureus2.core3.tracker.util.TRTrackerUtils;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.plugins.ui.UIInputReceiver;
+import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
 import org.gudy.azureus2.ui.swt.exporttorrent.wizard.ExportTorrentWizard;
 import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
 import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
 import org.gudy.azureus2.ui.swt.maketorrent.MultiTrackerEditor;
 import org.gudy.azureus2.ui.swt.maketorrent.TrackerEditorListener;
+import org.gudy.azureus2.ui.swt.maketorrent.WebSeedsEditor;
+import org.gudy.azureus2.ui.swt.maketorrent.WebSeedsEditorListener;
 import org.gudy.azureus2.ui.swt.minibar.DownloadBar;
+import org.gudy.azureus2.ui.swt.shells.AdvRenameWindow;
 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.views.ViewUtils;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.plugins.extseed.ExternalSeedPlugin;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
@@ -475,6 +483,102 @@ public class TorrentUtil {
 		
 		itemEditTracker.setEnabled(hasSelection);
 
+			// edit webseeds
+		
+		final MenuItem itemEditWebSeeds = new MenuItem(menuTracker, SWT.PUSH);
+		Messages.setLanguageText(itemEditWebSeeds, "MyTorrentsView.menu.editWebSeeds");
+		itemEditWebSeeds.addListener(SWT.Selection, new DMTask(dms) {
+			public void 
+			run(
+				final DownloadManager[] dms ) 
+			{
+				final TOTorrent torrent = dms[0].getTorrent();
+				
+				if ( torrent == null ){
+					
+					return;
+				}
+				
+				List getright = torrent.getAdditionalListProperty( "url-list" );
+				List webseeds = torrent.getAdditionalListProperty( "httpseeds" );
+				
+				Map ws = new HashMap();
+				
+				if ( getright == null ){
+					getright = new ArrayList();
+				}
+				
+				ws.put( "getright", getright );
+				
+				if ( webseeds == null ){
+					webseeds = new ArrayList();
+				}
+				
+				ws.put( "webseeds", webseeds );
+				
+				ws = BDecoder.decodeStrings( ws );
+				
+				new WebSeedsEditor(
+						null, ws,
+						new WebSeedsEditorListener()
+						{
+							public void 
+							webSeedsChanged(
+								String 	oldName,
+								String 	newName, 
+								Map 	ws ) 
+							{
+								try{
+										// String -> byte[] 
+									
+									ws = BDecoder.decode( BEncoder.encode( ws ));
+									
+									List	getright =  (List)ws.get( "getright" );
+									
+									if ( getright == null || getright.size() == 0 ){
+										
+										torrent.removeAdditionalProperty( "url-list" );
+										
+									}else{
+										
+										torrent.setAdditionalListProperty( "url-list", getright );
+									}
+									
+									List	webseeds =  (List)ws.get( "webseeds" );
+									
+									if ( webseeds == null || webseeds.size() == 0 ){
+										
+										torrent.removeAdditionalProperty( "httpseeds" );
+										
+									}else{
+										
+										torrent.setAdditionalListProperty( "httpseeds", webseeds );
+									}
+			
+									PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByClass(ExternalSeedPlugin.class);
+									
+									if ( pi != null ){
+										
+										ExternalSeedPlugin ext_seed_plugin = (ExternalSeedPlugin)pi.getPlugin();
+										
+										ext_seed_plugin.downloadChanged( PluginCoreUtils.wrap( dms[0] ));
+									}
+						
+								}catch (Throwable e){
+						
+									Debug.printStackTrace( e );
+								}
+							}
+						},
+						true );
+
+			}
+		});
+		
+		itemEditWebSeeds.setEnabled(dms.length==1);
+
+			// manual update
+		
 		final MenuItem itemManualUpdate = new MenuItem(menuTracker, SWT.PUSH);
 		Messages.setLanguageText(itemManualUpdate, "GeneralView.label.trackerurlupdate"); //$NON-NLS-1$
 		//itemManualUpdate.setImage(ImageRepository.getImage("edit_trackers"));
@@ -635,101 +739,16 @@ public class TorrentUtil {
 		itemFileClearResume.setEnabled(allStopped);
 
 		// Advanced - > Rename
-		final MenuItem itemRename = new MenuItem(menuAdvanced, SWT.CASCADE);
+		final MenuItem itemRename = new MenuItem(menuAdvanced, SWT.DROP_DOWN);
 		Messages.setLanguageText(itemRename, "MyTorrentsView.menu.rename");
-		itemRename.setEnabled(hasSelection);
-
-		final Menu menuRename = new Menu(composite.getShell(), SWT.DROP_DOWN);
-		itemRename.setMenu(menuRename);
-		
-		DownloadManager first_selected = (dms.length == 0) ? null : dms[0];
-		
-		// Advanced - > Rename -> Displayed Name
-		final MenuItem itemRenameDisplayed = new MenuItem(menuRename, SWT.CASCADE);
-		Messages.setLanguageText(itemRenameDisplayed, "MyTorrentsView.menu.rename.displayed");
-		itemRenameDisplayed.setEnabled(hasSelection);
-		if (itemRenameDisplayed.isEnabled()) {
-			itemRenameDisplayed.setData("suggested_text", first_selected.getDisplayName());
-			itemRenameDisplayed.setData("display_name", Boolean.TRUE);
-			itemRenameDisplayed.setData("save_name", Boolean.FALSE);
-			itemRenameDisplayed.setData("rename_all", Boolean.FALSE);
-			itemRenameDisplayed.setData("msg_key", "displayed");
-		}
-
-		// Rename -> Save Name
-		final MenuItem itemRenameSavePath = new MenuItem(menuRename, SWT.CASCADE);
-		Messages.setLanguageText(itemRenameSavePath, "MyTorrentsView.menu.rename.save_path");
-		itemRenameSavePath.setEnabled(fileMove && dms.length == 1);
-		if (itemRenameSavePath.isEnabled()) {
-			itemRenameSavePath.setData("suggested_text", first_selected.getAbsoluteSaveLocation().getName());
-			itemRenameSavePath.setData("display_name", Boolean.FALSE);
-			itemRenameSavePath.setData("save_name", Boolean.TRUE);
-			itemRenameSavePath.setData("rename_all", Boolean.FALSE);
-			itemRenameSavePath.setData("msg_key", "save_path");
-		}
-
-		// Rename -> Both
-		final MenuItem itemRenameBoth = new MenuItem(menuRename, SWT.CASCADE);
-		Messages.setLanguageText(itemRenameBoth, "MyTorrentsView.menu.rename.displayed_and_save_path");
-		itemRenameBoth.setEnabled(fileMove && dms.length == 1);
-		if (itemRenameBoth.isEnabled()) {
-			itemRenameBoth.setData("suggested_text", first_selected.getAbsoluteSaveLocation().getName());
-			itemRenameBoth.setData("display_name", Boolean.TRUE);
-			itemRenameBoth.setData("save_name", Boolean.TRUE);
-			itemRenameBoth.setData("msg_key", "displayed_and_save_path");
-			itemRenameBoth.setData("rename_all", Boolean.FALSE);
-		}
-
-		Listener rename_listener = new Listener() {
+		itemRename.setEnabled(hasSelection && dms.length == 1);
+		itemRename.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
-				MenuItem mi = (MenuItem) event.widget;
-				String suggested = (String) mi.getData("suggested_text");
-				final boolean rename_all = ((Boolean) mi.getData("rename_all")).booleanValue();
-				final boolean change_displayed_name = ((Boolean) mi.getData("display_name")).booleanValue();
-				final boolean change_save_name = ((Boolean) mi.getData("save_name")).booleanValue();
-				String msg_key_prefix = "MyTorrentsView.menu.rename." + (String) mi.getData("msg_key") + ".enter.";
-				SimpleTextEntryWindow text_entry = new SimpleTextEntryWindow();
-				text_entry.setTitle(msg_key_prefix + "title");
-				text_entry.setMessage(msg_key_prefix + "message");
-				text_entry.setPreenteredText(suggested, false);
-				text_entry.prompt();
-				if (text_entry.hasSubmittedInput()) {
-					String value = text_entry.getSubmittedInput();
-					final String value_to_set = (value.length() == 0) ? null : value;
-					DMTask task = new DMTask(dms) {
-						public void run(DownloadManager dm) {
-							if (rename_all) {
-								try {
-									dm.rename(value_to_set);
-								}
-								catch (Exception e) {
-									Logger.log(new LogAlert(dm, LogAlert.REPEATABLE,
-											"Download data rename operation failed", e));
-								}
-							}
-							if (change_displayed_name) {
-								dm.getDownloadState().setDisplayName(value_to_set);
-							}
-							if (change_save_name) {
-								try {
-									dm.renameDownload((value_to_set == null) ? dm.getDisplayName() : value_to_set);
-								}
-								catch (Exception e) {
-									Logger.log(new LogAlert(dm, LogAlert.REPEATABLE,
-											"Download data rename operation failed", e));
-								}
-							}
-						}
-					};
-					task.go();
-				}
+				AdvRenameWindow window = new AdvRenameWindow();
+				window.open(dms[0]);
 			}
-		};
+		});
 
-		itemRenameDisplayed.addListener(SWT.Selection, rename_listener);
-		itemRenameSavePath.addListener(SWT.Selection, rename_listener);
-		itemRenameBoth.addListener(SWT.Selection, rename_listener);
-		
 		// === advanced > export ===
 		// =========================
 
@@ -1040,38 +1059,41 @@ public class TorrentUtil {
 				SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
 						"MyTorrentsView.dialog.setPosition.title",
 						"MyTorrentsView.dialog.setPosition.text");
-				entryWindow.prompt();
-				if (!entryWindow.hasSubmittedInput()) {
-					return;
-				}
-				String sReturn = entryWindow.getSubmittedInput();
-
-				if (sReturn == null)
-					return;
-
-				int newPosition = -1;
-				try {
-					newPosition = Integer.valueOf(sReturn).intValue();
-				} catch (NumberFormatException er) {
-					// Ignore
-				}
-
-				int size = azureus_core.getGlobalManager().downloadManagerCount(
-						isSeedingView);
-				if (newPosition > size)
-					newPosition = size;
-
-				if (newPosition <= 0) {
-					MessageBox mb = new MessageBox(composite.getShell(), SWT.ICON_ERROR
-							| SWT.OK);
-					mb.setText(MessageText.getString("MyTorrentsView.dialog.NumberError.title"));
-					mb.setMessage(MessageText.getString("MyTorrentsView.dialog.NumberError.text"));
-
-					mb.open();
-					return;
-				}
-
-				moveSelectedTorrentsTo(tv, dms, newPosition);
+				entryWindow.prompt(new UIInputReceiverListener() {
+					public void UIInputReceiverClosed(UIInputReceiver entryWindow) {
+						if (!entryWindow.hasSubmittedInput()) {
+							return;
+						}
+						String sReturn = entryWindow.getSubmittedInput();
+						
+						if (sReturn == null)
+							return;
+						
+						int newPosition = -1;
+						try {
+							newPosition = Integer.valueOf(sReturn).intValue();
+						} catch (NumberFormatException er) {
+							// Ignore
+						}
+						
+						int size = azureus_core.getGlobalManager().downloadManagerCount(
+								isSeedingView);
+						if (newPosition > size)
+							newPosition = size;
+						
+						if (newPosition <= 0) {
+							MessageBox mb = new MessageBox(composite.getShell(), SWT.ICON_ERROR
+									| SWT.OK);
+							mb.setText(MessageText.getString("MyTorrentsView.dialog.NumberError.title"));
+							mb.setMessage(MessageText.getString("MyTorrentsView.dialog.NumberError.text"));
+							
+							mb.open();
+							return;
+						}
+						
+						moveSelectedTorrentsTo(tv, dms, newPosition);
+					}
+				});
 			}
 		});
 
@@ -1506,7 +1528,7 @@ public class TorrentUtil {
 		task.go();
 	}
 	
-	public static void promptUserForComment(DownloadManager[] dms) {
+	public static void promptUserForComment(final DownloadManager[] dms) {
 		if (dms.length == 0) {return;}
 		DownloadManager dm = dms[0];
 		
@@ -1518,18 +1540,21 @@ public class TorrentUtil {
 		text_entry.setMessage(msg_key_prefix + "message");
 		text_entry.setPreenteredText(suggested, false);
 		text_entry.setMultiLine(true);
-		text_entry.prompt();
-		
-		if (text_entry.hasSubmittedInput()) {
-			String value = text_entry.getSubmittedInput();
-			final String value_to_set = (value.length() == 0) ? null : value;
-			DMTask task = new DMTask(dms) {
-				public void run(DownloadManager dm) {
-					dm.getDownloadState().setUserComment(value_to_set);
+		text_entry.prompt(new UIInputReceiverListener() {
+			public void UIInputReceiverClosed(UIInputReceiver text_entry) {
+				if (text_entry.hasSubmittedInput()) {
+					String value = text_entry.getSubmittedInput();
+					final String value_to_set = (value.length() == 0) ? null : value;
+					DMTask task = new DMTask(dms) {
+						public void run(DownloadManager dm) {
+							dm.getDownloadState().setUserComment(value_to_set);
+						}
+					};
+					task.go();
 				}
-			};
-			task.go();
-		}
+			}
+		});
+		
 	}
 
 
@@ -1627,7 +1652,7 @@ public class TorrentUtil {
 		if (!sFirstChunk.startsWith("d")) {
 			if (parentShell != null) {
   			boolean isHTML = sFirstChunk.indexOf("<html") >= 0;
-  			MessageBoxShell boxShell = new MessageBoxShell(parentShell,
+  			MessageBoxShell boxShell = new MessageBoxShell(
   					MessageText.getString("OpenTorrentWindow.mb.notTorrent.title"),
   					MessageText.getString("OpenTorrentWindow.mb.notTorrent.text",
   							new String[] {
@@ -1639,7 +1664,7 @@ public class TorrentUtil {
   			if (isHTML) {
   				boxShell.setHtml(sFirstChunk);
   			}
-  			boxShell.open();
+  			boxShell.open(null);
 			}
 
 			return false;
diff --git a/org/gudy/azureus2/ui/swt/UIConfigDefaultsSWT.java b/org/gudy/azureus2/ui/swt/UIConfigDefaultsSWT.java
index 13b743c..9efbfc1 100644
--- a/org/gudy/azureus2/ui/swt/UIConfigDefaultsSWT.java
+++ b/org/gudy/azureus2/ui/swt/UIConfigDefaultsSWT.java
@@ -56,7 +56,6 @@ public class UIConfigDefaultsSWT
 		def.addParameter("GUI_SWT_bAlternateTablePainting", false);
 		def.addParameter("Colors.progressBar.override", false);
 		def.addParameter("GUI_SWT_DisableAlertSliding", false);
-		def.addParameter("SWT_bGTKTableBug", true);
 		def.addParameter("NameColumn.showProgramIcon", !Constants.isWindowsVista);
 		def.addParameter("Open MyTorrents", true);
 		def.addParameter("DND Always In Incomplete", false);
@@ -98,6 +97,7 @@ public class UIConfigDefaultsSWT
 		def.addParameter("GUI_SWT_bOldSpeedMenu", false);
 		
 		def.addParameter("ui.toolbar.uiswitcher", false);
+		def.addParameter("ui.systray.tooltip.enable", false);
 		
 		def.addParameter("ui", "az2");
 		
@@ -124,6 +124,8 @@ public class UIConfigDefaultsSWT
 		
 		
 		def.addParameter("MyTorrentsView.table.style", 0);
-    def.addParameter("MyTorrentsView.alwaysShowHeader", true);
+		def.addParameter("MyTorrentsView.alwaysShowHeader", true);
+		
+		def.addParameter("ConfigView.section.style.swt.library.selection", "cocoa");
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/UIExitUtilsSWT.java b/org/gudy/azureus2/ui/swt/UIExitUtilsSWT.java
index 4e768c2..f66aee6 100644
--- a/org/gudy/azureus2/ui/swt/UIExitUtilsSWT.java
+++ b/org/gudy/azureus2/ui/swt/UIExitUtilsSWT.java
@@ -132,16 +132,16 @@ public class UIExitUtilsSWT
 											});
 
 									MessageBoxShell mb = new MessageBoxShell(
-											Utils.findAnyShell(),
 											title,
 											text,
 											new String[] {
 												MessageText.getString("UpdateWindow.quit"),
 												MessageText.getString("Content.alert.notuploaded.button.abort")
-											}, 1, null, null, false, 0);
+											}, 1);
 									mb.setRelatedObject(((DownloadManager) flistUnfinished.get(0)));
 
-									return mb.open() == 0;
+									mb.open(null);
+									return mb.waitUntilClosed() == 0;
 								}
 							}, 0);
 				} else {
@@ -167,15 +167,15 @@ public class UIExitUtilsSWT
 											});
 
 									MessageBoxShell mb = new MessageBoxShell(
-											Utils.findAnyShell(),
 											title,
 											text,
 											new String[] {
 												MessageText.getString("UpdateWindow.quit"),
 												MessageText.getString("Content.alert.notuploaded.button.abort")
-											}, 1, null, null, false, 0);
+											}, 1);
 
-									return mb.open() == 0;
+									mb.open(null);
+									return mb.waitUntilClosed() == 0;
 								}
 							}, 0);
 				}
@@ -192,12 +192,12 @@ public class UIExitUtilsSWT
 	 * @author Rene Leonhardt
 	 */
 	private static boolean getExitConfirmation(boolean for_restart) {
-		int result = Utils.openMessageBox(Utils.findAnyShell(), SWT.ICON_WARNING
-				| SWT.YES | SWT.NO, for_restart
-				? "MainWindow.dialog.restartconfirmation"
+		MessageBoxShell mb = new MessageBoxShell(SWT.ICON_WARNING | SWT.YES
+				| SWT.NO, for_restart ? "MainWindow.dialog.restartconfirmation"
 				: "MainWindow.dialog.exitconfirmation", (String[]) null);
+		mb.open(null);
 
-		return result == SWT.YES;
+		return mb.waitUntilClosed() == SWT.YES;
 	}
 
 	public static void uiShutdown() {
diff --git a/org/gudy/azureus2/ui/swt/UISwitcherUtil.java b/org/gudy/azureus2/ui/swt/UISwitcherUtil.java
index 971681b..2278384 100644
--- a/org/gudy/azureus2/ui/swt/UISwitcherUtil.java
+++ b/org/gudy/azureus2/ui/swt/UISwitcherUtil.java
@@ -27,6 +27,8 @@ import java.util.Map;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.ui.UIInputReceiver;
+import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
 import org.gudy.azureus2.ui.swt.views.tableitems.files.FirstPieceItem;
 
 /**
@@ -38,190 +40,148 @@ public class UISwitcherUtil
 {
 	private static final long UPTIME_NEWUSER = 60 * 60 * 1; // 1 hour
 
-	private static boolean NOT_GOOD_ENOUGH_FOR_AZ2_USERS_YET = true;
-	
-	public static ArrayList listeners = new ArrayList();
-	
-	public static String lastUI = null;
-	
+	private static ArrayList listeners = new ArrayList();
+
+	private static String switchedToUI = null;
+
 	public static void addListener(UISwitcherListener l) {
 		listeners.add(l);
-		if (lastUI != null) {
-			triggerListeners(lastUI);
+		if (switchedToUI != null) {
+			triggerListeners(switchedToUI);
 		}
 	}
-	
+
 	public static void removeListener(UISwitcherListener l) {
 		listeners.remove(l);
 	}
 
-	public static String openSwitcherWindow(boolean bForceAsk) {
-		lastUI = _openSwitcherWindow(bForceAsk);
-		triggerListeners(lastUI);
-		return lastUI;
+	public static void openSwitcherWindow() {
+		_openSwitcherWindow();
 	}
-	
-	private static void triggerListeners(String ui) {
+
+	public static void triggerListeners(String ui) {
 		Object[] array = listeners.toArray();
 		for (int i = 0; i < array.length; i++) {
 			UISwitcherListener l = (UISwitcherListener) array[i];
 			l.uiSwitched(ui);
 		}
 	}
-	
-	public static String _openSwitcherWindow(boolean bForceAsk) {
-		Class uiswClass = null;
-		try {
-			uiswClass = Class.forName("com.aelitis.azureus.ui.swt.shells.uiswitcher.UISwitcherWindow");
-		} catch (ClassNotFoundException e1) {
+
+	public static String calcUIMode() {
+		if (!isAZ3Avail()) {
+			return "az2";
 		}
-		if (uiswClass == null) {
+
+		// Can't use Constants.isSafeMode - it's not set by the time we
+		// get here.
+		if ("1".equals(System.getProperty("azureus.safemode"))) {
+			// If we are in safe-mode, prefer the classic UI - less likely to cause problems.
 			return "az2";
 		}
 
-		if (!bForceAsk) {
-			
-			// Can't use Constants.isSafeMode - it's not set by the time we
-			// get here.
-			if ("1".equals(System.getProperty("azureus.safemode"))) {
-				// If we are in safe-mode, prefer the classic UI - less likely to cause problems.
-				return "az2";
-			}
-			
-			String lastUI = COConfigurationManager.getStringParameter("ui", "az2");
-			COConfigurationManager.setParameter("lastUI", lastUI);
-			
-			String forceUI = System.getProperty("force.ui");
-			if (forceUI != null) {
-				COConfigurationManager.setParameter("ui", forceUI);
-				return forceUI;
-			}
+		String lastUI = COConfigurationManager.getStringParameter("ui", "az2");
+		COConfigurationManager.setParameter("lastUI", lastUI);
+
+		String forceUI = System.getProperty("force.ui");
+		if (forceUI != null) {
+			COConfigurationManager.setParameter("ui", forceUI);
+			return forceUI;
+		}
+
+		// Flip people who install this client over top of an existing az
+		// to az3ui.  The installer will write a file to the program dir,
+		// while an upgrade won't
+		boolean installLogExists = FileUtil.getApplicationFile("installer.log").exists();
+		boolean alreadySwitched = COConfigurationManager.getBooleanParameter(
+				"installer.ui.alreadySwitched", false);
+		if (!alreadySwitched && installLogExists) {
+			COConfigurationManager.setParameter("installer.ui.alreadySwitched", true);
+			COConfigurationManager.setParameter("ui", "az3");
+			COConfigurationManager.setParameter("az3.virgin.switch", true);
+
+			return "az3";
+		}
 
-			// Flip people who install this client over top of an existing az
-			// to az3ui.  The installer will write a file to the program dir,
-			// while an upgrade won't
-			boolean installLogExists = FileUtil.getApplicationFile("installer.log").exists();
-			boolean alreadySwitched = COConfigurationManager.getBooleanParameter("installer.ui.alreadySwitched", false);
-			if (!alreadySwitched && installLogExists) {
-				COConfigurationManager.setParameter("installer.ui.alreadySwitched", true);
-				COConfigurationManager.setParameter("ui", "az3");
-				COConfigurationManager.setParameter("az3.virgin.switch", true);
-				
-				// Anyone who wasn't on az3 and had an old version "advanced mode"
-				if (!lastUI.equals("az3")) {
-					String sFirstVersion = COConfigurationManager.getStringParameter("First Recorded Version", Constants.AZUREUS_VERSION);
-					if (!Constants.getBaseVersion(sFirstVersion).equals(
-							Constants.getBaseVersion(Constants.AZUREUS_VERSION))) {
-						COConfigurationManager.setParameter("v3.Start Advanced", true);
+		boolean asked = COConfigurationManager.getBooleanParameter("ui.asked",
+				false);
+
+		if (asked || COConfigurationManager.hasParameter("ui", true)) {
+			return COConfigurationManager.getStringParameter("ui", "az3");
+		}
+
+		// Never auto-ask people who never have had 2.x, because they'd be scared
+		// and cry at the advanced coolness of the az2 ui
+		String sFirstVersion = COConfigurationManager.getStringParameter("First Recorded Version");
+		if (Constants.compareVersions(sFirstVersion, "3.0.0.0") >= 0) {
+			COConfigurationManager.setParameter("ui", "az3");
+			return "az3";
+		}
+
+		// For new users who install pre v3 Azureus, and then immediately upgrade 
+		// to v3:
+		// Give them v3 by default since they've (in theory) never used az2ui
+		// Note: Users with any existing 3.x.x.x version will not get because
+		//       they have the "ui" parameter set and there's logic above to
+		//       exit early.
+		try {
+			Map map = FileUtil.readResilientConfigFile("azureus.statistics");
+			if (map != null) {
+				Map overallMap = (Map) map.get("all");
+				if (overallMap != null) {
+					long uptime = 0;
+					Object uptimeObject = overallMap.get("uptime");
+					if (uptimeObject instanceof Number) {
+						uptime = ((Number) uptimeObject).longValue();
+					}
+					// during a previous azureus, we may have screwed up uptime
+					// and it might be zero.. so check for that..
+					if (uptime < UPTIME_NEWUSER && uptime >= 0) {
+						COConfigurationManager.setParameter("ui", "az3");
+						COConfigurationManager.setParameter("az3.virgin.switch", true);
+						COConfigurationManager.setParameter("az3.switch.immediate", true);
+						return "az3";
 					}
 				}
-				return "az3";
 			}
-			
-			boolean asked = COConfigurationManager.getBooleanParameter("ui.asked",
-					false);
+		} catch (Exception e) {
+			Debug.out(e);
+			// ignore
+		}
 
-			if (asked || COConfigurationManager.hasParameter("ui", true)) {
-				return COConfigurationManager.getStringParameter("ui", "az3");
-			}
+		// Short Circuit: We don't want to ask az2 users yet
+		COConfigurationManager.setParameter("ui", "az2");
+		return "az2";
+	}
 
-			// Never auto-ask people who never have had 2.x, because they'd be scared
-			// and cry at the advanced coolness of the az2 ui
-			String sFirstVersion = COConfigurationManager.getStringParameter("First Recorded Version");
-			if (Constants.compareVersions(sFirstVersion, "3.0.0.0") >= 0) {
-				COConfigurationManager.setParameter("ui", "az3");
-				return "az3";
-			}
-			
-			// For new users who install pre v3 Azureus, and then immediately upgrade 
-			// to v3:
-			// Give them v3 by default since they've (in theory) never used az2ui
-			// Note: Users with any existing 3.x.x.x version will not get because
-			//       they have the "ui" parameter set and there's logic above to
-			//       exit early.
-			try {
-  			Map map = FileUtil.readResilientConfigFile("azureus.statistics");
-  			if (map != null) {
-  				Map overallMap = (Map) map.get("all");
-  				if (overallMap != null) {
-      			long uptime = 0;
-      			Object uptimeObject = overallMap.get("uptime");
-      			if (uptimeObject instanceof Number) {
-      				uptime = ((Number)uptimeObject).longValue();
-      			}
-      			// during a previous azureus, we may have screwed up uptime
-      			// and it might be zero.. so check for that..
-      			if (uptime < UPTIME_NEWUSER && uptime >= 0) {
-      				COConfigurationManager.setParameter("ui", "az3");
-      				COConfigurationManager.setParameter("az3.virgin.switch", true);
-      				COConfigurationManager.setParameter("az3.switch.immediate", true);
-      				return "az3";
-      			}
-  				}
-  			}
-			} catch (Exception e) {
-				Debug.out(e);
-				// ignore
-			}
-			
-			// Short Circuit: We don't want to ask az2 users yet
-			if (NOT_GOOD_ENOUGH_FOR_AZ2_USERS_YET) {
-				COConfigurationManager.setParameter("ui", "az2");
-				return "az2";
-			}
+	public static void _openSwitcherWindow() {
+		Class uiswClass = null;
+		try {
+			uiswClass = Class.forName("com.aelitis.azureus.ui.swt.shells.uiswitcher.UISwitcherWindow");
+		} catch (ClassNotFoundException e1) {
+		}
+		if (uiswClass == null) {
+			return;
 		}
 
 		// either !asked or forceAsked at this point
 
 		try {
 
-			final int[] result = {
-				-1
-			};
-
-			final Class fuiswClass = uiswClass;
+			final Constructor constructor = uiswClass.getConstructor(new Class[] {});
 
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					try {
-						final Constructor constructor = fuiswClass.getConstructor(new Class[] {});
+			Object object = constructor.newInstance(new Object[] {});
 
-						Object object = constructor.newInstance(new Object[] {});
+			Method method = uiswClass.getMethod("open", new Class[] {});
 
-						Method method = fuiswClass.getMethod("open", new Class[] {});
+			method.invoke(object, new Object[] {});
 
-						Object resultObj = method.invoke(object, new Object[] {});
-
-						if (resultObj instanceof Number) {
-							result[0] = ((Number) resultObj).intValue();
-						}
-					} catch (Exception e) {
-						Debug.printStackTrace(e);
-					}
-				}
-			}, false);
-
-			if (result[0] == 0) {
-				// Full AZ3UI
-				COConfigurationManager.setParameter("ui", "az3");
-				// Anyone switching to az3 gets the "advanced mode"
-				if (!lastUI.equals("az3")) {
-					COConfigurationManager.setParameter("v3.Start Advanced", true);
-				}
-			} else if (result[0] == 1) {
-				COConfigurationManager.setParameter("ui", "az2");
-			}
-
-			if (result[0] != -1) {
-				COConfigurationManager.setParameter("ui.asked", true);
-			}
 		} catch (Exception e) {
 			Debug.printStackTrace(e);
 		}
 
-		return COConfigurationManager.getStringParameter("ui");
+		return;
 	}
-	
+
 	public static boolean isAZ3Avail() {
 		Class uiswClass = null;
 		try {
diff --git a/org/gudy/azureus2/ui/swt/Utils.java b/org/gudy/azureus2/ui/swt/Utils.java
index 335e3a9..fd09903 100644
--- a/org/gudy/azureus2/ui/swt/Utils.java
+++ b/org/gudy/azureus2/ui/swt/Utils.java
@@ -21,12 +21,13 @@
 
 package org.gudy.azureus2.ui.swt;
 
+import java.io.File;
 import java.util.*;
 import java.util.List;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.SWTException;
-import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.browser.Browser;
 import org.eclipse.swt.dnd.*;
 import org.eclipse.swt.events.*;
 import org.eclipse.swt.graphics.*;
@@ -38,12 +39,15 @@ import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.core3.util.Timer;
+import org.gudy.azureus2.platform.PlatformManager;
+import org.gudy.azureus2.platform.PlatformManagerCapabilities;
+import org.gudy.azureus2.platform.PlatformManagerFactory;
+import org.gudy.azureus2.plugins.platform.PlatformManagerException;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
-import org.gudy.azureus2.ui.swt.views.utils.VerticalAligner;
 
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
@@ -58,6 +62,10 @@ public class Utils
 	public static final String GOOD_STRING = "(/|,jI~`gy";
 
 	public static final boolean isGTK = SWT.getPlatform().equals("gtk");
+	
+	public static final boolean isCarbon = SWT.getPlatform().equals("carbon");
+
+	public static final boolean isCocoa = SWT.getPlatform().equals("cocoa");
 
 	/** Some platforms expand the last column to fit the remaining width of
 	 * the table.
@@ -67,11 +75,6 @@ public class Utils
 	/** GTK already handles alternating background for tables */
 	public static final boolean TABLE_GRIDLINE_IS_ALTERNATING_COLOR = isGTK;
 
-	private static final boolean DIRECT_SETCHECKED = !Constants.isOSX
-			|| SWT.getVersion() >= 3212;
-
-	public static final boolean SWT32_TABLEPAINT = SWT.getVersion() >= 3200;
-
 	/**
 	 * Debug/Diagnose SWT exec calls.  Provides usefull information like how
 	 * many we are queuing up, and how long each call takes.  Good to turn on
@@ -80,12 +83,14 @@ public class Utils
 	private static final boolean DEBUG_SWTEXEC = System.getProperty(
 			"debug.swtexec", "0").equals("1");
 
-	private static ArrayList queue;
+	private static ArrayList<Runnable> queue;
 
 	private static AEDiagnosticsLogger diag_logger;
 
 	private static Image[] shellIcons = null;
 
+	private static Image icon128;
+
 	private final static String[] shellIconNames = {
 		"azureus",
 		"azureus32",
@@ -97,9 +102,20 @@ public class Utils
 
 	static {
 		if (DEBUG_SWTEXEC) {
-			queue = new ArrayList();
+			queue = new ArrayList<Runnable>();
 			diag_logger = AEDiagnostics.getLogger("swt");
 			diag_logger.log("\n\nSWT Logging Starts");
+			
+			AEDiagnostics.addEvidenceGenerator(new AEDiagnosticsEvidenceGenerator(){
+				public void generate(IndentWriter writer) {
+					writer.println("SWT Queue:");
+					writer.indent();
+					for (Runnable r : queue) {
+						writer.println(r.toString());
+					}
+					writer.exdent();
+				}
+			});
 		} else {
 			queue = null;
 			diag_logger = null;
@@ -156,37 +172,12 @@ public class Utils
 		if (disposeList == null) {
 			return;
 		}
-		boolean bResourceObjectExists = SWT.getVersion() >= 3129;
-
 		for (int i = 0; i < disposeList.length; i++) {
 			Object o = disposeList[i];
 			if (o instanceof Widget && !((Widget) o).isDisposed())
 				((Widget) o).dispose();
-			else if (bResourceObjectExists && (o instanceof Resource)
-					&& !((Resource) o).isDisposed())
+			else if ((o instanceof Resource) && !((Resource) o).isDisposed()) {
 				((Resource) o).dispose();
-			else {
-				try {
-					// For Pre-SWT 3.1
-					if ((o instanceof Cursor) && !((Cursor) o).isDisposed()) {
-						((Cursor) o).dispose();
-					} else if ((o instanceof Font) && !((Font) o).isDisposed()) {
-						((Font) o).dispose();
-					} else if ((o instanceof GC) && !((GC) o).isDisposed()) {
-						((GC) o).dispose();
-					} else if ((o instanceof Image) && !((Image) o).isDisposed()) {
-						((Image) o).dispose();
-					} else if ((o instanceof Region) && !((Region) o).isDisposed()) {
-						((Region) o).dispose(); // 3.0
-					} else if ((o instanceof TextLayout)
-							&& !((TextLayout) o).isDisposed()) {
-						((TextLayout) o).dispose(); // 3.0
-					}
-				} catch (NoClassDefFoundError e) {
-					// ignore
-				}
-				// Path, Pattern, Transform are all 3.1, which will be instances of 
-				// Resource
 			}
 		}
 	}
@@ -232,10 +223,14 @@ public class Utils
 
 	public static void centreWindow(Shell shell) {
 		Rectangle displayArea; // area to center in
-		try {
-			displayArea = shell.getMonitor().getClientArea();
-		} catch (NoSuchMethodError e) {
-			displayArea = shell.getDisplay().getClientArea();
+		if (shell.getParent() != null) {
+			displayArea = shell.getParent().getBounds();
+		} else {
+  		try {
+  			displayArea = shell.getMonitor().getClientArea();
+  		} catch (NoSuchMethodError e) {
+  			displayArea = shell.getDisplay().getClientArea();
+  		}
 		}
 
 		Rectangle shellRect = shell.getBounds();
@@ -293,21 +288,12 @@ public class Utils
 			final boolean bAllowShareAdd, final Text url,
 			DropTargetListener dropTargetListener) {
 
-		Transfer[] transferList;
-		if (SWT.getVersion() >= 3107) {
-			transferList = new Transfer[] {
-				HTMLTransfer.getInstance(),
-				URLTransfer.getInstance(),
-				FileTransfer.getInstance(),
-				TextTransfer.getInstance()
-			};
-		} else {
-			transferList = new Transfer[] {
-				URLTransfer.getInstance(),
-				FileTransfer.getInstance(),
-				TextTransfer.getInstance()
-			};
-		}
+		Transfer[] transferList = new Transfer[] {
+			HTMLTransfer.getInstance(),
+			URLTransfer.getInstance(),
+			FileTransfer.getInstance(),
+			TextTransfer.getInstance()
+		};
 
 		final DropTarget dropTarget = new DropTarget(composite, DND.DROP_DEFAULT
 				| DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_TARGET_MOVE);
@@ -394,89 +380,6 @@ public class Utils
 		}
 	}
 
-	/**
-	 * Force label to use more vertical space if wrapped and in a GridLayout
-	 * Place this listener on the _parent_ of the label
-	 * See Eclipse SWT Bug #9866 (GridLayout does not handle wrapped Label properly)
-	 * This workaround only works for labels who:
-	 *   - horizontally span their whole parent 
-	 *     (ie. the parent has 3 columns, the label must span 3 columns)
-	 *   - GridData style has GridData.FILL_HORIZONTAL
-	 *   - Label style has SWT.WRAP
-	 *
-	 * @author TuxPaper
-	 * @note Bug 9866 fixed in 3105 and later
-	 */
-	public static class LabelWrapControlListener
-		extends ControlAdapter
-	{
-		public void controlResized(ControlEvent e) {
-			if (SWT.getVersion() >= 3105)
-				return;
-			Composite parent = (Composite) e.widget;
-			Control children[] = parent.getChildren();
-
-			if (children.length > 0) {
-				GridLayout parentLayout = (GridLayout) parent.getLayout();
-				if (parentLayout != null) {
-					Point size;
-					int marginWidth = parentLayout.marginWidth;
-
-					Composite grandParent = parent.getParent();
-					if (grandParent instanceof ScrolledComposite) {
-						Composite greatGP = grandParent.getParent();
-						if (greatGP != null) {
-							size = greatGP.getSize();
-
-							if (greatGP.getLayout() instanceof GridLayout) {
-								marginWidth += ((GridLayout) greatGP.getLayout()).marginWidth;
-							}
-						} else {
-							// not tested
-							size = grandParent.getSize();
-						}
-
-						if (grandParent.getLayout() instanceof GridLayout) {
-							marginWidth += ((GridLayout) grandParent.getLayout()).marginWidth;
-						}
-
-						ScrollBar sb = grandParent.getVerticalBar();
-						if (sb != null) {
-							// I don't know why, but we have to remove one
-							size.x -= sb.getSize().x + 1;
-						}
-					} else
-						size = parent.getSize();
-
-					boolean oneChanged = false;
-					for (int i = 0; i < children.length; i++) {
-						if ((children[i] instanceof Label)
-								&& (children[i].getStyle() & SWT.WRAP) == SWT.WRAP) {
-							GridData gd = (GridData) children[i].getLayoutData();
-							if (gd != null && gd.horizontalAlignment == GridData.FILL) {
-								if (gd.horizontalSpan == parentLayout.numColumns) {
-									gd.widthHint = size.x - 2 * marginWidth;
-									oneChanged = true;
-								} else {
-									Point pt = children[i].getLocation();
-									gd.widthHint = size.x - pt.x - (2 * marginWidth);
-									oneChanged = true;
-								}
-							}
-						}
-					}
-					if (oneChanged) {
-						parent.layout(true);
-						if (grandParent instanceof ScrolledComposite) {
-							((ScrolledComposite) grandParent).setMinSize(parent.computeSize(
-									SWT.DEFAULT, SWT.DEFAULT, true));
-						}
-					}
-				}
-			} // size
-		} // controlResized
-	} // class
-
 	public static void alternateRowBackground(TableItem item) {
 		if (Utils.TABLE_GRIDLINE_IS_ALTERNATING_COLOR) {
 			if (!item.getParent().getLinesVisible())
@@ -570,6 +473,33 @@ public class Utils
 	 */
 	public static void setShellIcon(Shell shell) {
 		if (Constants.isOSX) {
+			if (true) {
+				return;
+			}
+			if (icon128 == null) {
+  			ImageLoader imageLoader = ImageLoader.getInstance();
+  			icon128 = imageLoader.getImage("azureus128");
+  			if (Constants.isCVSVersion()) {
+  				final int border = 9;
+					Image image = Utils.createAlphaImage(shell.getDisplay(),
+							128 + (border * 2), 128 + (border * 2));
+					image = blitImage(shell.getDisplay(), icon128, null, image, new Point(border,
+							border + 1));
+					imageLoader.releaseImage("azureus128");
+					icon128 = image;
+//  				GC gc = new GC(icon128);
+//  				gc.setTextAntialias(SWT.ON);
+//  				gc.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_YELLOW));
+//  				Font font = getFontWithHeight(gc.getFont(), gc, 20, SWT.BOLD);
+//  				gc.setFont(font);
+//					GCStringPrinter.printString(gc, Constants.AZUREUS_VERSION,
+//							new Rectangle(0, 0, 128, 128), false, false, SWT.CENTER
+//									| SWT.BOTTOM);
+//  				gc.dispose();
+//  				font.dispose();
+  			}
+			}
+ 			shell.setImage(icon128);
 			return;
 		}
 
@@ -745,9 +675,15 @@ public class Utils
 
 								queue.remove(code);
 
-								diag_logger.log(SystemTime.getCurrentTime()
-										+ "] - Q. size=" + queue.size() + ";wait:" + wait
-										+ "ms;run:" + runTIme + "ms");
+								if (runTIme > 10) {
+									diag_logger.log(SystemTime.getCurrentTime()
+											+ "] - Q. size=" + queue.size() + ";wait:" + wait
+											+ "ms;run:" + runTIme + "ms " + code);
+								} else {
+									diag_logger.log(SystemTime.getCurrentTime()
+											+ "] - Q. size=" + queue.size() + ";wait:" + wait
+											+ "ms;run:" + runTIme + "ms");
+								}
 							}
 						}
 					};
@@ -820,153 +756,6 @@ public class Utils
 		return (display.getThread() == Thread.currentThread());
 	}
 
-	/** Open a messagebox using resource keys for title/text
-	 * 
-	 * @param parent Parent shell for messagebox
-	 * @param style SWT styles for messagebox
-	 * @param keyPrefix message bundle key prefix used to get title and text.  
-	 *         Title will be keyPrefix + ".title", and text will be set to
-	 *         keyPrefix + ".text"
-	 * @param textParams any parameters for text
-	 * 
-	 * @return what the messagebox returns
-	 */
-	public static int openMessageBox(Shell parent, int style, String keyPrefix,
-			String[] textParams) {
-		if ((style & (0x7f << 5)) == 0) {
-			// need at least one button
-			style |= SWT.OK;
-		}
-		Object[] buttonInfo = swtButtonStylesToText(style);
-		MessageBoxShell mb = new MessageBoxShell(parent,
-				MessageText.getString(keyPrefix + ".title"), MessageText.getString(
-						keyPrefix + ".text", textParams), (String[]) buttonInfo[0], 0);
-		mb.setLeftImage(style & 0x1f);
-		int ret = mb.open();
-
-		Integer[] buttonVals = (Integer[]) buttonInfo[1];
-		if (ret < 0 || ret > buttonVals.length) {
-			return SWT.CANCEL;
-		}
-		return buttonVals[ret].intValue();
-	}
-
-	/** Open a messagebox with actual title and text
-	 * 
-	 * @param parent
-	 * @param style
-	 * @param title
-	 * @param text
-	 * @return
-	 */
-	public static int openMessageBox(Shell parent, int style, String title,
-			String text) {
-		if (parent == null) {
-			parent = findAnyShell();
-		}
-		if ((style & (0x7f << 5)) == 0) {
-			// need at least one button
-			style |= SWT.OK;
-		}
-
-		Object[] buttonInfo = swtButtonStylesToText(style);
-		MessageBoxShell mb = new MessageBoxShell(parent, title, text,
-				(String[]) buttonInfo[0], 0);
-		mb.setLeftImage(style & 0x1f);
-		int ret = mb.open();
-
-		Integer[] buttonVals = (Integer[]) buttonInfo[1];
-		if (ret < 0 || ret > buttonVals.length) {
-			return SWT.CANCEL;
-		}
-		return buttonVals[ret].intValue();
-	}
-
-	public static int openMessageBox(Shell parent, int style, int default_style,
-			String title, String text) {
-		if (parent == null) {
-			parent = findAnyShell();
-		}
-		if ((style & (0x7f << 5)) == 0) {
-			// need at least one button
-			style |= SWT.OK;
-		}
-
-		Object[] buttonInfo = swtButtonStylesToText(style);
-
-		Object[] defaultButtonInfo = swtButtonStylesToText(default_style);
-
-		int defaultIndex = 0;
-
-		if (defaultButtonInfo.length > 0) {
-			String name = ((String[]) defaultButtonInfo[0])[0];
-
-			String[] names = (String[]) buttonInfo[0];
-
-			for (int i = 0; i < names.length; i++) {
-				if (names[i].equals(name)) {
-					defaultIndex = i;
-					break;
-				}
-			}
-		}
-		MessageBoxShell mb = new MessageBoxShell(parent, title, text,
-				(String[]) buttonInfo[0], defaultIndex);
-		mb.setLeftImage(style & 0x1f);
-		int ret = mb.open();
-
-		Integer[] buttonVals = (Integer[]) buttonInfo[1];
-		if (ret < 0 || ret > buttonVals.length) {
-			return SWT.CANCEL;
-		}
-		return buttonVals[ret].intValue();
-	}
-
-	private static Object[] swtButtonStylesToText(int style) {
-		List buttons = new ArrayList(2);
-		List buttonVal = new ArrayList(2);
-		int buttonCount = 0;
-		if ((style & SWT.OK) > 0) {
-			buttons.add(MessageText.getString("Button.ok"));
-			buttonVal.add(new Integer(SWT.OK));
-			buttonCount++;
-		}
-		if ((style & SWT.YES) > 0) {
-			buttons.add(MessageText.getString("Button.yes"));
-			buttonVal.add(new Integer(SWT.YES));
-			buttonCount++;
-		}
-		if ((style & SWT.NO) > 0) {
-			buttons.add(MessageText.getString("Button.no"));
-			buttonVal.add(new Integer(SWT.NO));
-			buttonCount++;
-		}
-		if ((style & SWT.CANCEL) > 0) {
-			buttons.add(MessageText.getString("Button.cancel"));
-			buttonVal.add(new Integer(SWT.CANCEL));
-			buttonCount++;
-		}
-		if ((style & SWT.ABORT) > 0) {
-			buttons.add(MessageText.getString("Button.abort"));
-			buttonVal.add(new Integer(SWT.ABORT));
-			buttonCount++;
-		}
-		if ((style & SWT.RETRY) > 0) {
-			buttons.add(MessageText.getString("Button.retry"));
-			buttonVal.add(new Integer(SWT.RETRY));
-			buttonCount++;
-		}
-		if ((style & SWT.IGNORE) > 0) {
-			buttons.add(MessageText.getString("Button.ignore"));
-			buttonVal.add(new Integer(SWT.IGNORE));
-			buttonCount++;
-		}
-		return new Object[] {
-			(String[]) buttons.toArray(new String[buttonCount]),
-			(Integer[]) buttonVal.toArray(new Integer[buttonCount])
-		};
-	}
-
 	/**
 	 * Bottom Index may be negative. Returns bottom index even if invisible.
 	 */
@@ -1023,21 +812,23 @@ public class Utils
 		if (sFile == null || sFile.trim().length() == 0) {
 			return;
 		}
-
-		if (SWT.getVersion() >= 3315 || SWT.getVersion() < 3300
-				|| UrlUtils.isURL(sFile) || sFile.startsWith("mailto:")) {
-			boolean launched = Program.launch(sFile);
-			if (!launched && Constants.isUnix
-					&& (UrlUtils.isURL(sFile) || sFile.startsWith("mailto:"))) {
-				if (!Program.launch("xdg-open " + sFile)) {
-					Program.launch("htmlview " + sFile);
+		
+		if (new File(sFile).isDirectory()) {
+			PlatformManager mgr = PlatformManagerFactory.getPlatformManager();
+			if (mgr.hasCapability(PlatformManagerCapabilities.ShowFileInBrowser)) {
+				try {
+					PlatformManagerFactory.getPlatformManager().showFile(sFile);
+					return;
+				} catch (PlatformManagerException e) {
 				}
 			}
-		} else {
-			if (Constants.isOSX) {
-				Program.launch("file://" + sFile.replaceAll(" ", "%20"));
-			} else {
-				Program.launch(sFile);
+		}
+
+		boolean launched = Program.launch(sFile);
+		if (!launched && Constants.isUnix
+				&& (UrlUtils.isURL(sFile) || sFile.startsWith("mailto:"))) {
+			if (!Program.launch("xdg-open " + sFile)) {
+				Program.launch("htmlview " + sFile);
 			}
 		}
 	}
@@ -1051,29 +842,26 @@ public class Utils
 	 */
 	public static void setCheckedInSetData(final TableItem item,
 			final boolean checked) {
-		if (DIRECT_SETCHECKED) {
-			item.setChecked(checked);
-		} else {
-			item.setChecked(!checked);
-			item.getDisplay().asyncExec(new AERunnable() {
-				public void runSupport() {
-					item.setChecked(checked);
-				}
-			});
-		}
+		item.setChecked(checked);
 
 		if (Constants.isWindowsXP || isGTK) {
 			Rectangle r = item.getBounds(0);
 			Table table = item.getParent();
 			Rectangle rTable = table.getClientArea();
 
-			r.y += VerticalAligner.getTableAdjustVerticalBy(table);
 			table.redraw(0, r.y, rTable.width, r.height, true);
 		}
 	}
 
 	public static boolean linkShellMetricsToConfig(final Shell shell,
 			final String sConfigPrefix) {
+		boolean isMaximized = COConfigurationManager.getBooleanParameter(sConfigPrefix
+				+ ".maximized");
+		
+		if (!isMaximized) {
+			shell.setMaximized(false);
+		}
+
 		String windowRectangle = COConfigurationManager.getStringParameter(
 				sConfigPrefix + ".rectangle", null);
 		boolean bDidResize = false;
@@ -1096,12 +884,9 @@ public class Utils
 			}
 		}
 
-		boolean isMaximized = COConfigurationManager.getBooleanParameter(sConfigPrefix
-				+ ".maximized");
-		if (Constants.isOSX && windowRectangle != null) {
-			isMaximized = false;
+		if (isMaximized) {
+			shell.setMaximized(isMaximized);
 		}
-		shell.setMaximized(isMaximized);
 
 		new ShellMetricsResizeListener(shell, sConfigPrefix);
 
@@ -1130,7 +915,7 @@ public class Utils
 
 		private int calcState(Shell shell) {
 			return shell.getMinimized() ? SWT.MIN : shell.getMaximized()
-					&& !Constants.isOSX ? SWT.MAX : SWT.NONE;
+					&& !isCarbon ? SWT.MAX : SWT.NONE;
 		}
 
 		private void saveMetrics() {
@@ -1918,6 +1703,21 @@ public class Utils
 		return false;
 	}
 
+	public static Shell findFirstShellWithStyle(int styles) {
+		Display display = Display.getCurrent();
+		if (display != null) {
+			Shell[] shells = display.getShells();
+			for (int i = 0; i < shells.length; i++) {
+				Shell shell = shells[i];
+				int style = shell.getStyle();
+				if ((style & styles) == styles && !shell.isDisposed()) {
+					return shell;
+				}
+			}
+		}
+		return null;
+	}
+
 	public static int[] colorToIntArray(Color color) {
 		if (color == null || color.isDisposed()) {
 			return null;
@@ -2284,6 +2084,8 @@ public class Utils
 	
 	
 	private static Map truncatedTextCache = new HashMap();
+
+	private static ThreadPool tp = new ThreadPool("GetOffSWT", 2);
 	
 	private static class TruncatedTextResult {
 		String text;
@@ -2379,7 +2181,6 @@ public class Utils
 	{
 		MessageBoxShell mb = 
 			new MessageBoxShell(
-				findAnyShell(),
 				MessageText.getString("ConfigView.section.security.op.error.title"),
 				MessageText.getString("ConfigView.section.security.op.error",
 						new String[] {
@@ -2390,6 +2191,26 @@ public class Utils
 				},
 				0 );
 		
-		mb.open();
+		mb.open(null);
+	}
+	
+	public static void getOffOfSWTThread(AERunnable runnable) {
+		tp.run(runnable);
+	}
+	
+	public static Browser createSafeBrowser(Composite parent, int style) {
+		try {
+  		Browser browser = new Browser(parent, Utils.getInitialBrowserStyle(style));
+  		browser.addDisposeListener(new DisposeListener() {
+  			public void widgetDisposed(DisposeEvent e) {
+  				((Browser)e.widget).setUrl("about:blank");
+  				((Browser)e.widget).setVisible(false);
+  				while (!e.display.isDisposed() && e.display.readAndDispatch());
+  			}
+  		});
+  		return browser;
+		} catch (Throwable e) {
+		}
+		return null;
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/associations/AssociationChecker.java b/org/gudy/azureus2/ui/swt/associations/AssociationChecker.java
index 25ddd16..4af1ef7 100644
--- a/org/gudy/azureus2/ui/swt/associations/AssociationChecker.java
+++ b/org/gudy/azureus2/ui/swt/associations/AssociationChecker.java
@@ -41,6 +41,7 @@ import org.gudy.azureus2.platform.PlatformManagerCapabilities;
 import org.gudy.azureus2.platform.PlatformManagerFactory;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 
 import org.gudy.azureus2.plugins.platform.PlatformManagerException;
@@ -106,7 +107,7 @@ AssociationChecker
 		if (display.isDisposed())
 			return;
 
- 		shell = new Shell (display,SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+ 		shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
  	
  		Utils.setShellIcon(shell);
 	 	shell.setText(MessageText.getString("dialog.associations.title"));
diff --git a/org/gudy/azureus2/ui/swt/auth/AuthenticatorWindow.java b/org/gudy/azureus2/ui/swt/auth/AuthenticatorWindow.java
index 05f4629..6bef7b2 100644
--- a/org/gudy/azureus2/ui/swt/auth/AuthenticatorWindow.java
+++ b/org/gudy/azureus2/ui/swt/auth/AuthenticatorWindow.java
@@ -34,6 +34,7 @@ import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.ui.swt.*;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 
 import org.gudy.azureus2.core3.internat.MessageText;
@@ -401,7 +402,7 @@ AuthenticatorWindow
 			}
 			
 				
-	 		shell = new Shell (display,SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+	 		shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
 	 	
 	 		Utils.setShellIcon(shell);
 		 	Messages.setLanguageText(shell, "authenticator.title");
diff --git a/org/gudy/azureus2/ui/swt/auth/CertificateCreatorWindow.java b/org/gudy/azureus2/ui/swt/auth/CertificateCreatorWindow.java
index a95cb6b..92955f2 100644
--- a/org/gudy/azureus2/ui/swt/auth/CertificateCreatorWindow.java
+++ b/org/gudy/azureus2/ui/swt/auth/CertificateCreatorWindow.java
@@ -41,6 +41,7 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 
 
@@ -93,7 +94,7 @@ CertificateCreatorWindow
 				return;
 			}
 			
-			shell = new Shell (display,SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+			shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
 			
 			Utils.setShellIcon(shell);
 			Messages.setLanguageText(shell, "security.certcreate.title");
diff --git a/org/gudy/azureus2/ui/swt/auth/CertificateTrustWindow.java b/org/gudy/azureus2/ui/swt/auth/CertificateTrustWindow.java
index 096e376..fc4f199 100644
--- a/org/gudy/azureus2/ui/swt/auth/CertificateTrustWindow.java
+++ b/org/gudy/azureus2/ui/swt/auth/CertificateTrustWindow.java
@@ -40,6 +40,7 @@ import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 
 
@@ -103,7 +104,7 @@ CertificateTrustWindow
 				return;
 			}
 			
-			shell = new Shell (display,SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+			shell =  ShellFactory.createMainShell(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
 			
 			Utils.setShellIcon(shell);
 			shell.setText(MessageText.getString("security.certtruster.title"));
diff --git a/org/gudy/azureus2/ui/swt/auth/CryptoWindow.java b/org/gudy/azureus2/ui/swt/auth/CryptoWindow.java
index cf1f8c4..e0495a0 100644
--- a/org/gudy/azureus2/ui/swt/auth/CryptoWindow.java
+++ b/org/gudy/azureus2/ui/swt/auth/CryptoWindow.java
@@ -35,6 +35,8 @@ import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.ui.swt.*;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
+import org.gudy.azureus2.ui.swt.components.shell.ShellManager;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
@@ -85,15 +87,7 @@ CryptoWindow
 		try{
 			if ( display.getThread() == Thread.currentThread()){
 				
-				display.syncExec(
-						new Runnable() 
-						{
-							public void
-							run()
-							{
-								dialog[0] = new cryptoDialog( sem, display, handler_type, action_type, last_pw_incorrect, reason );
-							}
-						});
+				dialog[0] = new cryptoDialog( sem, display, handler_type, action_type, last_pw_incorrect, reason );
 				
 				while ( !( display.isDisposed() || sem.isReleasedForever())){
 					
@@ -189,7 +183,8 @@ CryptoWindow
 				return;
 			}
 			
-	 		shell = new Shell( display,SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+			shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM
+					| SWT.APPLICATION_MODAL);
 	 	
 	 		Utils.setShellIcon(shell);
 	 		
diff --git a/org/gudy/azureus2/ui/swt/components/BufferedGraphicTableItem1.java b/org/gudy/azureus2/ui/swt/components/BufferedGraphicTableItem1.java
index 83a0a96..5af5950 100644
--- a/org/gudy/azureus2/ui/swt/components/BufferedGraphicTableItem1.java
+++ b/org/gudy/azureus2/ui/swt/components/BufferedGraphicTableItem1.java
@@ -29,8 +29,6 @@ import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Table;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.BufferedTableRow;
-import org.gudy.azureus2.ui.swt.views.table.impl.TableCellImpl;
-import org.gudy.azureus2.ui.swt.views.utils.VerticalAligner;
 
 /** Draws an image at a column in a row of a table using direct paints to the 
  *  table.
@@ -42,7 +40,6 @@ import org.gudy.azureus2.ui.swt.views.utils.VerticalAligner;
  * Cons:
  *  - Bug - overpainting of table causing our cell to redraw everytime any other cell redraws
  *          (New for Windows since SWT3.0M8, always been there for linux)
- *  - Bug - incorrect drawing location on linux (new to SWT3.0M8)
  *  - other bugs
  *
  * @see BufferedGraphicTable2
@@ -165,13 +162,17 @@ public abstract class BufferedGraphicTableItem1 extends BufferedTableItemImpl
     }
 
     Rectangle tableBounds = table.getClientArea();
-    if (bounds.y + bounds.height - tableBounds.y < table.getHeaderHeight()
-				|| bounds.y > tableBounds.height) {
-//    	System.out.println("doPnt#" + row.getIndex() + ": "
-//					+ (bounds.y + bounds.height - tableBounds.y) + "<" + tableBounds.y
-//					+ " || " + bounds.y + " > " + tableBounds.height);
-      return;
-    }
+		// Cocoa calls paintitem while row is below tablearea, and painting there
+		// is valid!
+		if (!Utils.isCocoa) {
+      if (bounds.y + bounds.height - tableBounds.y < table.getHeaderHeight()
+  				|| bounds.y > tableBounds.height) {
+      	//System.out.println("doPnt#" + row.getIndex() + ": "
+  			//		+ (bounds.y + bounds.height - tableBounds.y) + "<" + tableBounds.y
+  			//		+ " || " + bounds.y + " > " + tableBounds.height);
+        return;
+      }
+		}
     
     boolean fits = (imageBounds.width == bounds.width
 				&& imageBounds.height == bounds.height);
@@ -185,11 +186,6 @@ public abstract class BufferedGraphicTableItem1 extends BufferedTableItemImpl
           gc = new GC(table);
         }
         if (gc != null) {
-          int iAdj = VerticalAligner.getTableAdjustVerticalBy(table);
-          bounds.y += iAdj;
-          iAdj = VerticalAligner.getTableAdjustHorizontallyBy(table);
-          bounds.x += iAdj;
-
           gc.drawImage(image, bounds.x, bounds.y);
           if (ourGC) {
             gc.dispose();
@@ -235,23 +231,6 @@ public abstract class BufferedGraphicTableItem1 extends BufferedTableItemImpl
       return;
     }
 
-    // See Eclipse Bug 42416
-    // "[Platform Inconsistency] GC(Table) has wrong origin"
-    // Notes/Questions:
-    // - GTK's "new GC(table)" starts under header, instead of above
-    //   -- so, adjust bounds up
-    // - Appears to apply to new GC(table) AND GC passed by PaintEvent from a Table PaintListener
-    // - Q) .height may be effected (smaller than it should be).  How does this effect clipping?
-    // - Q) At what version does this bug start appearing?
-    //   A) Reports suggest at least 2.1.1
-    int iAdj = VerticalAligner.getTableAdjustVerticalBy(table);
-    bounds.y += iAdj;
-    clipping.y += iAdj;
-    // New: GTK M8+ has a bounds.x bug.. works fine in M7, but assume people have M8 or higher (3.0final)
-    iAdj = VerticalAligner.getTableAdjustHorizontallyBy(table);
-    bounds.x += iAdj;
-    clipping.x += iAdj;
-
     boolean ourGC = (gc == null);
     if (ourGC) {
       gc = new GC(table);
diff --git a/org/gudy/azureus2/ui/swt/components/BufferedTableItemImpl.java b/org/gudy/azureus2/ui/swt/components/BufferedTableItemImpl.java
index 2555703..edc2691 100644
--- a/org/gudy/azureus2/ui/swt/components/BufferedTableItemImpl.java
+++ b/org/gudy/azureus2/ui/swt/components/BufferedTableItemImpl.java
@@ -22,11 +22,9 @@
 package org.gudy.azureus2.ui.swt.components;
 
 import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Table;
 
 import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Utils;
 
 /**
@@ -45,42 +43,48 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 	
 	private Image icon = null;
 
+	private AERunnable runnableDirtyCell;
+
 	public BufferedTableItemImpl(BufferedTableRow row, int position) {
 		this.row = row;
 		this.position = position;
 	}
 
 	public String getText() {
-		if (Utils.SWT32_TABLEPAINT) {
-			return text;
-		}
-
-		if (position != -1)
-			return row.getText(position);
-		return "";
+		return text;
 	}
 
 	public boolean setText(String text) {
-		if (Utils.SWT32_TABLEPAINT) {
-			if (this.text.equals(text)) {
-				return false;
-			}
-	
-			this.text = (text == null) ? "" : text;
-			
-			Rectangle bounds = getBounds();
-			if (bounds != null) {
-				Table table = row.getTable();
-				Rectangle dirty = table.getClientArea().intersection(bounds);
-				table.redraw(dirty.x, dirty.y, dirty.width, dirty.height, false);
+		if (this.text.equals(text)) {
+			return false;
+		}
+		this.text = (text == null) ? "" : text;
+		
+		dirtyCell();
+		
+		return true;
+	}
+	private void dirtyCell() {
+		if (runnableDirtyCell == null) {
+			synchronized (this) {
+				if (runnableDirtyCell == null) {
+					runnableDirtyCell = new AERunnable(){
+						public void runSupport() {
+							Rectangle bounds = getBounds();
+							if (bounds != null) {
+								Table table = row.getTable();
+								Rectangle dirty = table.getClientArea().intersection(bounds);
+								//System.out.println("old = " + this.text + ";new=" + text + ";dirty=" + bounds);
+								
+								table.redraw(dirty.x, dirty.y, dirty.width, dirty.height, false);
+							}
+						}
+					};
+				}
 			}
-			
-			return true;
 		}
-
-		if (position != -1)
-			return row.setText(position, text);
-		return false;
+		
+		Utils.execSWTThread(runnableDirtyCell);
 	}
 
 	public void setIcon(Image img) {
@@ -224,6 +228,8 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 
   // @see org.gudy.azureus2.ui.swt.components.BufferedTableItem#redraw()
   public void redraw() {
+		//System.out.println("redraw via " + Debug.getCompressedStackTrace(5));
+
   	Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
 				Rectangle bounds = getBounds();
diff --git a/org/gudy/azureus2/ui/swt/components/BufferedTruncatedLabel.java b/org/gudy/azureus2/ui/swt/components/BufferedTruncatedLabel.java
index 1661a21..8e7ed94 100644
--- a/org/gudy/azureus2/ui/swt/components/BufferedTruncatedLabel.java
+++ b/org/gudy/azureus2/ui/swt/components/BufferedTruncatedLabel.java
@@ -117,7 +117,7 @@ BufferedTruncatedLabel
   }
   
   public void setCursor(Cursor cursor) {
-  	if (isDisposed()) {
+  	if (isDisposed() || cursor == null || cursor.isDisposed()) {
   		return;
   	}
     label.setCursor(cursor);
diff --git a/org/gudy/azureus2/ui/swt/components/shell/LightBoxShell.java b/org/gudy/azureus2/ui/swt/components/shell/LightBoxShell.java
deleted file mode 100644
index 8c169a3..0000000
--- a/org/gudy/azureus2/ui/swt/components/shell/LightBoxShell.java
+++ /dev/null
@@ -1,503 +0,0 @@
-package org.gudy.azureus2.ui.swt.components.shell;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.mainwindow.IMainWindow;
-
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-
-public class LightBoxShell
-{
-
-	private Shell lbShell = null;
-
-	private Shell parentShell = null;
-
-	private int insetTop = 0;
-
-	private int insetBottom = 0;
-
-	private int insetLeft = 0;
-
-	private int insetRight = 0;
-
-	private boolean closeOnESC = false;
-
-	private boolean isAlreadyOpened = false;
-
-	private Display display;
-
-	private UIFunctionsSWT uiFunctions;
-
-	private boolean isBusy = false;
-
-	/**
-	 * An array to hold the off-line images for the spinner
-	 */
-	private Image[] spinnerImages = null;
-
-	private Rectangle spinnerBounds = null;
-
-	/**
-	 * Indicates that the spinner is already animating
-	 */
-	private boolean busyAlready = false;
-
-	/**
-	 * The canvas to display the spinner
-	 */
-	private Canvas spinnerCanvas = null;
-
-	private Rectangle shellBounds = null;
-
-	private boolean parentActivatedOnce = false;
-
-	public static final int RESIZE_VERTICAL = 1 << 1;
-
-	public static final int RESIZE_HORIZONTAL = 1 << 2;
-
-	private int styleMask = RESIZE_VERTICAL | RESIZE_HORIZONTAL;
-
-	private int alphaLevel = 178;
-
-	public LightBoxShell() {
-		this(false);
-	}
-
-	/**
-	 * Creates a LightBoxShell without opening it
-	 * @param closeOnESC if <code>true</code> then the ESC key can be used to dismiss the lightbox
-	 */
-	public LightBoxShell(boolean closeOnESC) {
-		this.closeOnESC = closeOnESC;
-
-		parentShell = getUIFunctions().getMainShell();
-
-		if (null == parentShell) {
-			return;
-		}
-		IMainWindow mainWindow = getUIFunctions().getMainWindow();
-		Rectangle r = mainWindow.getMetrics(IMainWindow.WINDOW_ELEMENT_STATUSBAR);
-		setInsets(0, r.height, 0, 0);
-		createControls();
-	}
-
-	public LightBoxShell(Shell parentShell, boolean closeOnESC) {
-		this.parentShell = parentShell;
-		this.closeOnESC = closeOnESC;
-		createControls();
-	}
-
-	public void setInsets(int top, int bottom, int left, int right) {
-		this.insetTop = top;
-		this.insetBottom = bottom;
-		this.insetLeft = left;
-		this.insetRight = right;
-		if (null != lbShell && false == lbShell.isDisposed()) {
-			if (true == isAlreadyOpened()) {
-				lbShell.setBounds(getBounds(true));
-			}
-		}
-	}
-
-	private void createControls() {
-		if (null == parentShell) {
-			return;
-		}
-
-		lbShell = new Shell(parentShell, SWT.NO_TRIM);
-
-		if (true == Constants.isOSX) {
-			getUIFunctions().createMainMenu(lbShell);
-		}
-
-		display = parentShell.getDisplay();
-
-		/*
-		* Trap and prevent the ESC key from closing the shell
-		*/
-		if (true == closeOnESC) {
-			lbShell.addListener(SWT.Traverse, new Listener() {
-				public void handleEvent(Event e) {
-					if (e.detail == SWT.TRAVERSE_ESCAPE) {
-						e.doit = false;
-						close();
-					}
-				}
-			});
-		}
-
-		/*
-		 * For OSX add this listener to make sure that the parent shell and
-		 * the lighbox shell behave like they are sandwiched together; without this
-		 * then external applications can slide in between the parent shell and the
-		 * lightbox which creates a strange visual effect 
-		 */
-		if (true == Constants.isOSX) {
-			lbShell.addShellListener(new ShellAdapter() {
-				public void shellActivated(ShellEvent e) {
-					if (null != parentShell && false == parentShell.isDisposed()) {
-
-						/*
-						 * Making sure we are only performing this only once for each time the lbShell is activated;
-						 * without this we will run into a StackOverflow as the 2 shells go back and forth activating each other
-						 */
-						if (false == parentActivatedOnce) {
-							parentActivatedOnce = true;
-							parentShell.forceActive();
-						} else {
-							parentActivatedOnce = false;
-						}
-					}
-				}
-			});
-		}
-
-		lbShell.addDisposeListener(new DisposeListener() {
-			public void widgetDisposed(DisposeEvent e) {
-				/*
-				 * Disposing all the spinner images
-				 */
-				if (null != spinnerImages) {
-					spinnerImages = null;
-				}
-			}
-
-		});
-
-		/*
-		 * Add a listener to the parent shell and move/resize the lightbox to fit over it
-		 */
-		final ControlListener moveAndResizeListener = new ControlListener() {
-			public void controlMoved(ControlEvent e) {
-				shellBounds = null;
-				getBounds();
-				lbShell.setLocation(shellBounds.x, shellBounds.y);
-			}
-
-			public void controlResized(ControlEvent e) {
-
-				if ((styleMask & RESIZE_HORIZONTAL) != 0
-						&& (styleMask & RESIZE_VERTICAL) != 0) {
-					shellBounds = null;
-					getBounds();
-					lbShell.setSize(shellBounds.width, shellBounds.height);
-				} else if ((styleMask & RESIZE_HORIZONTAL) != 0) {
-					shellBounds = null;
-					getBounds();
-					lbShell.setSize(shellBounds.width, lbShell.getSize().y);
-				} else if ((styleMask & RESIZE_VERTICAL) != 0) {
-					shellBounds = null;
-					getBounds();
-					lbShell.setSize(lbShell.getSize().x, shellBounds.height);
-				}
-			}
-		};
-
-		parentShell.addControlListener(moveAndResizeListener);
-
-		/*
-		 * When the lightbox is disposed remove the listener from the parent so we don't leave it dangling
-		 */
-		lbShell.addDisposeListener(new DisposeListener() {
-			public void widgetDisposed(DisposeEvent e) {
-				parentShell.removeControlListener(moveAndResizeListener);
-			}
-		});
-
-	}
-
-	private UIFunctionsSWT getUIFunctions() {
-		if (null == uiFunctions) {
-			uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-			if (null == uiFunctions) {
-				throw new NullPointerException(
-						"An initialized instance of UIFunctionsSWT is required to create a LightBoxShell");
-			}
-		}
-		return uiFunctions;
-	}
-
-	public void open(boolean dim) {
-		if (null != lbShell && false == lbShell.isDisposed()) {
-
-			lbShell.setBounds(getBounds());
-			isAlreadyOpened = true;
-
-			/*
-			 * Black mask with 30% transparency
-			 */
-			lbShell.setBackground(Colors.black);
-
-			try {
-				lbShell.setAlpha(alphaLevel);
-			} catch (Throwable t) {
-				//Do nothing if alpha is not supported
-			}
-
-			if (dim) {
-				lbShell.open();
-			}
-		}
-	}
-
-	public void close() {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				if (null != lbShell && false == lbShell.isDisposed()) {
-					lbShell.dispose();
-				}
-			}
-		});
-	}
-
-	/**
-	 * Returns the current bounds of the LightBox
-	 * @return
-	 */
-	public Rectangle getBounds() {
-		return getBounds(false);
-	}
-
-	/**
-	 * Returns the bounds of the LightBox; recalculate before returning if specified
-	 * @param recalculate
-	 * @return if <code>true</code> then recalculate the bounds before returning
-	 */
-	private Rectangle getBounds(boolean recalculate) {
-		if (false == recalculate && null != shellBounds) {
-			return new Rectangle(shellBounds.x, shellBounds.y, shellBounds.width,
-					shellBounds.height);
-		}
-
-		shellBounds = parentShell.getClientArea();
-		Point parentLocation = parentShell.toDisplay(insetLeft, insetTop);
-		shellBounds.x = parentLocation.x;
-		shellBounds.y = parentLocation.y;
-		shellBounds.width -= insetRight + insetLeft;
-		shellBounds.height -= insetTop + insetBottom;
-		return new Rectangle(shellBounds.x, shellBounds.y, shellBounds.width,
-				shellBounds.height);
-	}
-
-	/**
-	 * 
-	 * Creates a stylized shell with pre-defined look and feel
-	 * @param borderWidth
-	 * @param closeLightboxOnExit if <code>true</code> then close the parent lightbox when this pop-up is closed; otherwise leave it opened
-	 * @return
-	 */
-	public StyledShell createPopUpShell(int borderWidth,
-			boolean closeLightboxOnExit) {
-		return createPopUpShell(borderWidth, closeLightboxOnExit, true);
-	}
-
-	/**
-	 * Creates a stylized shell with pre-defined look and feel
-	 * @param borderWidth is used for the width of the custom dialog trim; is not in effect if standard trim is specified
-	 * @param closeLightboxOnExit if <code>true</code> then close the parent lightbox when this pop-up is closed; otherwise leave it opened
-	 * @param useCustomTrim if <code>true</code> use our custom dialog trim; otherwise use default OS dialog trims 
-	 * @return
-	 */
-	public StyledShell createPopUpShell(int borderWidth,
-			boolean closeLightboxOnExit, boolean useCustomTrim) {
-		StyledShell newShell = new StyledShell(lbShell, borderWidth, useCustomTrim);
-
-		if (true == closeLightboxOnExit) {
-			newShell.addListener(SWT.Dispose, new Listener() {
-				public void handleEvent(Event event) {
-					close();
-				}
-			});
-
-		}
-		return newShell;
-	}
-
-	/**
-	 * Centers and opens the given shell and closes the light box when the given shell is closed
-	 * @param shellToOpen
-	 */
-	public void open(StyledShell shellToOpen, boolean dim) {
-		if (null != shellToOpen && null != lbShell) {
-
-			if (false == isAlreadyOpened) {
-				open(dim);
-			}
-
-			if (false == shellToOpen.isAlreadyOpened()) {
-				shellToOpen.open();
-			}
-		}
-	}
-
-	public void setCursor(Cursor cursor) {
-		if (null != lbShell && false == lbShell.isDisposed()) {
-			lbShell.setCursor(cursor);
-		}
-	}
-
-	public void setData(String key, Object value) {
-		if (null != lbShell && false == lbShell.isDisposed()) {
-			lbShell.setData(key, value);
-		}
-	}
-
-	public Display getDisplay() {
-		return display;
-	}
-
-	public boolean isAlreadyOpened() {
-		return isAlreadyOpened;
-	}
-
-	public void addDisposeListener(DisposeListener listener) {
-		lbShell.addDisposeListener(listener);
-	}
-
-	/**
-	 * Show a spinning indicator that a process is busy
-	 * @param value if <code>true</code> then show the spinner; if <code>false</code> then stop showing the spinner
-	 * @param delayInMilli the delay in milliseconds before the spinner is shown; is only in effect when isBusy is <code>true</code>
-	 */
-	public void showBusy(boolean value, long delayInMilli) {
-		if (value == isBusy) {
-			return;
-		}
-		isBusy = value;
-
-		if (true == isBusy && false == busyAlready) {
-			showSpinner(Math.max(0, delayInMilli));
-		}
-	}
-
-	private void showSpinner(final long delayInMilli) {
-
-		/*
-		 * Create the images off-line and store them in the array if not done already;
-		 * we will use these to draw onto the canvas to animate the spinner
-		 */
-		if (null == spinnerImages) {
-			ImageLoader imageLoader = ImageLoader.getInstance();
-			spinnerImages = imageLoader.getImages("spinner_big");
-			if (spinnerImages.length == 0) {
-				return;
-			}
-
-			int w = 0;
-			int h = 0;
-			for (int i = 0; i < spinnerImages.length; i++) {
-				Image image = spinnerImages[i];
-				Rectangle bounds = image.getBounds();
-				w = Math.max(w, bounds.width);
-				h = Math.max(w, bounds.height);
-			}
-			spinnerBounds = new Rectangle(0, 0, w, h);
-			
-			lbShell.addDisposeListener(new DisposeListener() {
-				public void widgetDisposed(DisposeEvent e) {
-					ImageLoader imageLoader = ImageLoader.getInstance();
-					imageLoader.releaseImage("spinner_big");
-				}
-			});
-		}
-
-		/*
-		 * Adjust the spinner bounds to be centered on the lightbox shell itself
-		 */
-		Utils.centerRelativeTo(spinnerBounds, getBounds());
-		Point to_lbShell = lbShell.toControl(spinnerBounds.x, spinnerBounds.y);
-		spinnerBounds.x = to_lbShell.x;
-		spinnerBounds.y = to_lbShell.y;
-
-		final int[] imageDataIndex = new int[1];
-		/*
-		 * Create the canvas for the spinner; size the canvas to be just enough for the image
-		 */
-		if (null == spinnerCanvas) {
-			spinnerCanvas = new Canvas(lbShell, SWT.NONE);
-			spinnerCanvas.addPaintListener(new PaintListener() {
-				public void paintControl(PaintEvent e) {
-					e.gc.drawImage(spinnerImages[imageDataIndex[0]], 0, 0);
-				}
-			});
-		}
-		spinnerCanvas.setBackground(lbShell.getBackground());
-		spinnerCanvas.setBounds(spinnerBounds);
-
-		/*
-		 * Spinner animation 
-		 */
-		
-		Utils.execSWTThreadLater(100, new AERunnable() {
-			public void runSupport() {
-				if (!isBusy || spinnerImages == null) {
-					busyAlready = false;
-					return;
-				}
-				
-				busyAlready = true;
-				if (null != spinnerCanvas && false == spinnerCanvas.isDisposed()) {
-					spinnerCanvas.redraw();
-					spinnerCanvas.update();
-				}
-
-				/* 
-				 * If we have just drawn the last image start over from the beginning
-				 */
-				if (imageDataIndex[0] == spinnerImages.length - 1) {
-					imageDataIndex[0] = 0;
-				} else {
-					imageDataIndex[0]++;
-				}
-
-				Utils.execSWTThreadLater(100, this);
-			}
-		});
-	}
-
-	public int getStyleMask() {
-		return styleMask;
-	}
-
-	public void setStyleMask(int styleMask) {
-		this.styleMask = styleMask;
-	}
-
-	public int getAlphaLevel() {
-		return alphaLevel;
-	}
-
-	public void setAlphaLevel(final int alphaLevel) {
-		this.alphaLevel = alphaLevel;
-
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				if (lbShell.isDisposed()) {
-					return;
-				}
-				try {
-					lbShell.setAlpha(alphaLevel);
-				} catch (Throwable t) {
-					//Do nothing if alpha is not supported
-				}
-			}
-		});
-	}
-
-	public void moveAbove(Control control) {
-		lbShell.moveAbove(control);
-	}
-
-	public Shell getShell() {
-		return lbShell;
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/components/shell/ShellFactory.java b/org/gudy/azureus2/ui/swt/components/shell/ShellFactory.java
index f8b29e3..ef99036 100644
--- a/org/gudy/azureus2/ui/swt/components/shell/ShellFactory.java
+++ b/org/gudy/azureus2/ui/swt/components/shell/ShellFactory.java
@@ -23,9 +23,13 @@ package org.gudy.azureus2.ui.swt.components.shell;
  */
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
+
+import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
@@ -243,8 +247,28 @@ public final class ShellFactory
 					uiFunctions.bringToFront();
 				}
 			}
-
-			super.open();
+			
+			Shell firstShellWithStyle = Utils.findFirstShellWithStyle(SWT.APPLICATION_MODAL);
+			if (firstShellWithStyle != null && firstShellWithStyle != this) {
+				// ok, there's a window with application_modal set, which on OSX will mean
+				// that if we open our window, it will be on top, but users won't be able
+				// to interact with it.  So, wait until the modal window goes away..
+				firstShellWithStyle.addDisposeListener(new DisposeListener() {
+					public void widgetDisposed(DisposeEvent e) {
+						// wait for dispose to complete, then run open again to check for
+						// any new application modal shells to wait for
+						Utils.execSWTThreadLater(0, new AERunnable() {
+							public void runSupport() {
+								AEShell.this.open();
+							}
+						});
+					}
+				});
+				firstShellWithStyle.setVisible(true);
+				firstShellWithStyle.forceActive();
+			} else {
+				super.open();
+			}
 		}
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/components/shell/StyledShell.java b/org/gudy/azureus2/ui/swt/components/shell/StyledShell.java
deleted file mode 100644
index d5fd39c..0000000
--- a/org/gudy/azureus2/ui/swt/components/shell/StyledShell.java
+++ /dev/null
@@ -1,649 +0,0 @@
-package org.gudy.azureus2.ui.swt.components.shell;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Cursor;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.graphics.Region;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Monitor;
-import org.eclipse.swt.widgets.Shell;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.ui.swt.Utils;
-
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-
-public class StyledShell
-{
-
-	public static final int HINT_ALIGN_CENTER = 1 << 1;
-
-	public static final int HINT_ALIGN_FIT_IN_MONITOR = 1 << 2;
-
-	public static final int HINT_ALIGN_NONE = 1 << 0;
-
-	private Shell parentShell;
-
-	private Shell styledShell;
-
-	private Display display;
-
-	private Composite borderedBackground;
-
-	private Composite content;
-
-	private int borderWidth;
-
-	private boolean isAlreadyOpened = false;
-
-	private int alpha = 255; //230; // Disabled because this doesn't work via VNC (and possibly other places)
-
-	private boolean isAnimating = false;
-
-	/**
-	 * A reference to the screen monitor that the shell is in;
-	 * this is used to ensure that subsequent resizing or repositioning operations
-	 * are performed relative to this monitor.
-	 */
-	private Monitor monitor = null;
-
-	private boolean useCustomTrim = true;
-
-	private Region region;
-
-	private boolean isAlphaSupported = true;
-
-	private UIFunctionsSWT uiFunctions;
-
-	/**
-	 * 
-	 * @param parentShell
-	 * @param borderWidth
-	 */
-	public StyledShell(Shell parentShell, int borderWidth) {
-		this(parentShell, borderWidth, true);
-	}
-
-	/**
-	 * 
-	 * @param parentShell
-	 * @param borderWidth
-	 * @param useCustomTrim
-	 */
-	public StyledShell(Shell parentShell, int borderWidth, boolean useCustomTrim) {
-		this.parentShell = parentShell;
-		this.borderWidth = borderWidth;
-		this.useCustomTrim = useCustomTrim;
-
-		if (null == parentShell) {
-			throw new NullPointerException("parentShell can not be null");
-		}
-
-		/*
-		 * Quick check to see if alpha is supported
-		 */
-		try {
-			parentShell.setAlpha(parentShell.getAlpha());
-		} catch (Throwable t) {
-			isAlphaSupported = false;
-		}
-
-		display = parentShell.getDisplay();
-
-		if (true == useCustomTrim) {
-
-			createCustomShell();
-
-			/*
-			 * Must dispose of the Region explicitly when we're done; region is only used when custom trim is used
-			 */
-			if (null != styledShell) {
-				styledShell.addDisposeListener(new DisposeListener() {
-					public void widgetDisposed(DisposeEvent e) {
-						if (null != region && false == region.isDisposed()) {
-							region.dispose();
-						}
-					}
-				});
-			}
-
-		} else {
-			createStandardShell();
-		}
-
-	}
-
-	/**
-	 * Creates a pop-up shell with out custom style and trim
-	 */
-	private void createCustomShell() {
-		styledShell = ShellFactory.createShell(parentShell, getShellStyle(SWT.NONE));
-		FillLayout fillLayout = new FillLayout();
-		fillLayout.marginHeight = borderWidth;
-		fillLayout.marginWidth = borderWidth;
-		styledShell.setLayout(fillLayout);
-
-		if (true == Constants.isOSX) {
-			getUIFunctions().createMainMenu(styledShell);
-		}
-
-		borderedBackground = new Composite(styledShell, SWT.NONE);
-
-		fillLayout = new FillLayout();
-		fillLayout.marginHeight = borderWidth;
-		fillLayout.marginWidth = borderWidth;
-		borderedBackground.setLayout(fillLayout);
-
-		content = new Composite(borderedBackground, SWT.DOUBLE_BUFFERED);
-		content.setBackgroundMode(SWT.INHERIT_DEFAULT);
-
-		setBackground(ColorCache.getColor(styledShell.getDisplay(), 38, 38, 38));
-		content.setBackground(ColorCache.getColor(styledShell.getDisplay(), 13, 13,
-				13));
-		content.setForeground(ColorCache.getColor(styledShell.getDisplay(), 206,
-				206, 206));
-
-		borderedBackground.addPaintListener(new PaintListener() {
-
-			public void paintControl(PaintEvent e) {
-
-				Rectangle bounds = borderedBackground.getClientArea();
-				int r = StyledShell.this.borderWidth;
-				int d = r * 2;
-
-				try {
-					e.gc.setAntialias(SWT.ON);
-				} catch (Throwable t) {
-					//Do nothing if it's not supported
-				}
-
-				/*
-				 * Fills the four corners with the StyleShell background color so it blends in with the shell
-				 */
-				e.gc.setBackground(styledShell.getBackground());
-				e.gc.fillRectangle(0, 0, r, r);
-				e.gc.fillRectangle(bounds.width - r, 0, r, r);
-				e.gc.fillRectangle(bounds.width - r, bounds.height - r, r, r);
-				e.gc.fillRectangle(0, bounds.height - r, r, r);
-
-				/*
-				 * Then paint in the rounded-corner rectangle
-				 */
-				e.gc.setBackground(content.getBackground());
-
-				/*
-				 * Paint the 4 circles for the rounded corners; these circles will partially overlap
-				 * on top of the four corners drawn above to give the look of a rounded corner
-				 */
-				e.gc.fillPolygon(circle(r, r, r));
-				e.gc.fillPolygon(circle(r, r, bounds.height - r));
-				e.gc.fillPolygon(circle(r, bounds.width - r, r));
-				e.gc.fillPolygon(circle(r, bounds.width - r, bounds.height - r));
-
-				/*
-				 * Rectangle connecting between the top-left and top-right circles
-				 */
-				e.gc.fillRectangle(new Rectangle(r, 0, bounds.width - d, r));
-
-				/*
-				 * Rectangle connecting between the bottom-left and bottom-right circles
-				 */
-				e.gc.fillRectangle(new Rectangle(r, bounds.height - r,
-						bounds.width - d, r));
-
-				/*
-				 * Rectangle to fill the area between the 2 bars created above
-				 */
-				e.gc.fillRectangle(new Rectangle(0, r, bounds.width, bounds.height - d));
-			}
-
-		});
-
-		Listener l = new Listener() {
-			int startX, startY;
-
-			public void handleEvent(Event e) {
-				if (e.type == SWT.KeyDown && e.character == SWT.ESC) {
-					styledShell.dispose();
-				}
-				if (e.type == SWT.MouseDown && e.button == 1) {
-					startX = e.x;
-					startY = e.y;
-				}
-				if (e.type == SWT.MouseMove && (e.stateMask & SWT.BUTTON1) != 0) {
-					Point p = styledShell.toDisplay(e.x, e.y);
-					p.x -= startX;
-					p.y -= startY;
-					styledShell.setLocation(p);
-				}
-				if (e.type == SWT.Resize) {
-					styledShell.setRegion(getRoundedRegion(styledShell.getBounds()));
-				}
-			}
-		};
-		styledShell.addListener(SWT.KeyDown, l);
-		styledShell.addListener(SWT.MouseDown, l);
-		styledShell.addListener(SWT.MouseMove, l);
-		styledShell.addListener(SWT.Resize, l);
-		styledShell.setCursor(display.getSystemCursor(SWT.CURSOR_SIZEALL));
-		content.setCursor(display.getSystemCursor(SWT.CURSOR_ARROW));
-	}
-
-	/**
-	 * Creates a pop-up shell with standard dialog style and trim
-	 */
-	private void createStandardShell() {
-		styledShell = ShellFactory.createShell(parentShell, getShellStyle(SWT.APPLICATION_MODAL));
-		FillLayout fillLayout = new FillLayout();
-		fillLayout.marginHeight = 0;
-		fillLayout.marginWidth = 0;
-		styledShell.setLayout(fillLayout);
-
-		if (true == Constants.isOSX) {
-			getUIFunctions().createMainMenu(styledShell);
-		}
-		Utils.setShellIcon(styledShell);
-
-		content = new Composite(styledShell, SWT.DOUBLE_BUFFERED);
-		content.setBackgroundMode(SWT.INHERIT_DEFAULT);
-
-		alpha = 255;
-
-	}
-
-	/**
-	 * Returns the bit mask for the proper shell style
-	 * @param style
-	 * @return
-	 */
-	private int getShellStyle(int style) {
-		/*
-		 * If there are any other shell on top that also has a title then bring this shell on top of that
-		 * so it is not obscured by the other shell(s); conversely DO NOT bring this shell on top if the 
-		 * above condition is false so that it will not obscure other windows like external browser, etc...
-		 */
-		//		if (true == Utils.anyShellHaveStyle(SWT.ON_TOP | SWT.TITLE)) {
-		//			UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-		//			if (uiFunctions != null && uiFunctions.getMainShell() != null) {
-		//				style |= SWT.ON_TOP;
-		//			}
-		//		}
-		/*
-		 * 
-		 * On non-osx set the NO_TRIM flag and on OSX ONLY set the NO_TRIM flag if setAlpha()
-		 * is also supported.  Versions of SWT on OSX that do not support setAlpha() also can not render
-		 * the embedded web page properly if the NO_TRIM flag is set; the NO_TRIM flag allows us to draw
-		 * a round-cornered shell.  Without this flag the shell corners would just be the normal square angle. 
-		 */
-		if (true == useCustomTrim) {
-			if (true == Constants.isOSX) {
-				if (true == isAlphaSupported) {
-					style |= SWT.NO_TRIM;
-				}
-			} else {
-				style |= SWT.NO_TRIM;
-			}
-
-			return style;
-		}
-		return style | SWT.DIALOG_TRIM | SWT.RESIZE;
-	}
-
-	private Region getRoundedRegion(Rectangle bounds) {
-
-		int r = borderWidth;
-		int d = r * 2;
-
-		/*
-		 * Must explicitly dispose of any previous reference to a Region before assigning a new one
-		 */
-		if (null != region && false == region.isDisposed()) {
-			region.dispose();
-		}
-
-		region = new Region();
-
-		/*
-		 * Add the 4 circles for the rounded corners
-		 */
-		region.add(circle(r, r, r));
-		region.add(circle(r, r, bounds.height - r));
-		region.add(circle(r, bounds.width - r, r));
-		region.add(circle(r, bounds.width - r, bounds.height - r));
-
-		/*
-		 * Rectangle connecting between the top-left and top-right circles
-		 */
-		region.add(new Rectangle(r, 0, bounds.width - d, r));
-
-		/*
-		 * Rectangle connecting between the bottom-left and bottom-right circles
-		 */
-		region.add(new Rectangle(r, bounds.height - r, bounds.width - d, r));
-
-		/*
-		 * Rectangle to fill the area between the 2 bars created above
-		 */
-		region.add(new Rectangle(0, r, bounds.width, bounds.height - d));
-
-		return region;
-	}
-
-	private int[] circle(int r, int offsetX, int offsetY) {
-		int[] polygon = new int[8 * r + 4];
-		//x^2 + y^2 = r^2
-		for (int i = 0; i < 2 * r + 1; i++) {
-			int x = i - r;
-			int y = (int) Math.sqrt(r * r - x * x);
-			polygon[2 * i] = offsetX + x;
-			polygon[2 * i + 1] = offsetY + y;
-			polygon[8 * r - 2 * i - 2] = offsetX + x;
-			polygon[8 * r - 2 * i - 1] = offsetY - y;
-		}
-		return polygon;
-	}
-
-	public void addListener(int eventType, Listener listener) {
-		if (true == isAlive()) {
-			styledShell.addListener(eventType, listener);
-		}
-	}
-
-	public void open() {
-		if (true == isAlive()) {
-			/*
-			 * Get the monitor that the mouse cursor is in
-			 */
-			Point cursorLocation = display.getCursorLocation();
-			monitor = Utils.getMonitor(cursorLocation);
-
-			styledShell.open();
-			isAlreadyOpened = true;
-		}
-	}
-
-	public void close() {
-		if (true == isAlive()) {
-			styledShell.close();
-			isAlreadyOpened = false;
-		}
-	}
-
-	public void forceActive() {
-		if (true == isAlive()) {
-			styledShell.setVisible(true);
-			styledShell.forceActive();
-		}
-	}
-
-	public void pack() {
-		if (true == isAlive()) {
-			styledShell.pack();
-		}
-	}
-
-	public void pack(boolean changed) {
-		if (true == isAlive()) {
-			styledShell.pack(changed);
-		}
-	}
-
-	public void setSize(int width, int height) {
-		/*
-		 * If the shell is opened already then, by default, resizing should not try to center the shell
-		 */
-		setSize(width, height, (false == isAlreadyOpened ? HINT_ALIGN_CENTER : 0));
-	}
-
-	public void setSize(int width, int height, int hint) {
-		if (true == isAlive()) {
-			Rectangle outerBounds = styledShell.getBounds();
-
-			if (true == useCustomTrim) {
-				/*
-				 * Compensating since the 2 outer custom borders extends beyond the content area
-				 */
-				width += borderWidth * 4;
-				height += borderWidth * 4;
-			} else {
-				/*
-				 * Compensating since the dialog trim extends beyond the bounds of the content area
-				 */
-				width += styledShell.getBounds().width
-						- styledShell.getClientArea().width;
-				height += styledShell.getBounds().height
-						- styledShell.getClientArea().height;
-			}
-
-			if (outerBounds.width != width || outerBounds.height != height) {
-
-				outerBounds.width = width;
-				outerBounds.height = height;
-
-				/*
-				 * Centers the the StyleShell relative to main application window
-				 */
-				if ((hint & HINT_ALIGN_CENTER) != 0) {
-					Utils.centerRelativeTo(outerBounds,
-							getUIFunctions().getMainShell().getBounds());
-				}
-
-				/*
-				 * Adjust the new bounds if the shell does not fully fit on the screen.
-				 * If a monitor is already present then adjust the bounds relative to the monitor;
-				 * otherwise make it relative to the monitor the cursor resides in
-				 */
-				if ((hint & HINT_ALIGN_FIT_IN_MONITOR) != 0) {
-					if (null != monitor) {
-						Utils.makeVisibleOnMonitor(outerBounds, monitor);
-					} else {
-						Utils.makeVisibleOnCursor(outerBounds);
-					}
-				}
-
-				styledShell.setBounds(outerBounds);
-
-				/*
-				 * Only custom trim needs custom region
-				 */
-				if (true == useCustomTrim) {
-					styledShell.setRegion(getRoundedRegion(outerBounds));
-				}
-
-				styledShell.forceActive();
-			}
-		}
-	}
-
-	public void centersShell() {
-		if (true == isAlive()) {
-			Rectangle bounds = styledShell.getBounds();
-			Utils.centerRelativeTo(bounds,
-					getUIFunctions().getMainShell().getBounds());
-			styledShell.setBounds(bounds);
-		}
-	}
-
-	public void makeShellVisible() {
-		if (true == isAlive()) {
-			/*
-			 * Adjust the new bounds if the shell does not fully fit on the screen.
-			 * If a monitor is already present then adjust the bounds relative to the monitor;
-			 * otherwise make it relative to the monitor the cursor resides in
-			 */
-			Rectangle bounds = styledShell.getBounds();
-			if (null != monitor) {
-				Utils.makeVisibleOnMonitor(bounds, monitor);
-			} else {
-				Utils.makeVisibleOnCursor(bounds);
-			}
-			styledShell.setBounds(bounds);
-		}
-	}
-
-	/**
-	 * Animates the visibility of the shell from 0 to the appropriate alpha level; this creates the effect
-	 * of a pop-up fading into view
-	 * @param milliSeconds
-	 */
-	public void animateFade(final int milliSeconds) {
-		if (false == isAlive() || true == isAnimating || false == isAlphaSupported) {
-			return;
-		}
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				if (!isAlive()) {
-					return;
-				}
-				isAnimating = true;
-				try {
-					int seconds = milliSeconds;
-					int currentAlpha = 0;
-					int delay = 3;
-					int sleepIncrement = milliSeconds / (10 + delay);
-					if (true == isAlive()) {
-						setAlpha(styledShell, currentAlpha);
-						styledShell.setVisible(true);
-					}
-					while (seconds > 0) {
-						Thread.sleep(sleepIncrement);
-						seconds -= (sleepIncrement);
-						if (true == isAlive()) {
-							/*
-							 * We don't update the alpha for a few cycles to allow the shell to initialize it's content
-							 * while still remaining invisible
-							 */
-							if (delay <= 0) {
-								setAlpha(styledShell, Math.min(currentAlpha, alpha));
-								currentAlpha += 20;
-							}
-							delay--;
-						} else {
-							break;
-						}
-					}
-				} catch (InterruptedException e) {
-					e.printStackTrace();
-				} finally {
-					if (true == isAlive()) {
-						setAlpha(styledShell, alpha);
-					}
-					isAnimating = false;
-					styledShell.forceActive();
-				}
-			}
-		});
-
-	}
-
-	public void setVisible(boolean visible) {
-		if (true == isAlive()) {
-			styledShell.setVisible(visible);
-		}
-	}
-
-	public void removeListener(int eventType, Listener listener) {
-		if (true == isAlive()) {
-			styledShell.removeListener(eventType, listener);
-		}
-	}
-
-	public void setCursor(Cursor cursor) {
-		if (true == isAlive()) {
-			styledShell.setCursor(cursor);
-		}
-	}
-
-	public void setData(String key, Object value) {
-		if (true == isAlive()) {
-			styledShell.setData(key, value);
-		}
-	}
-
-	public boolean isAlive() {
-		if (null == styledShell || true == styledShell.isDisposed()) {
-			return false;
-		}
-		return true;
-	}
-
-	public Composite getContent() {
-		return content;
-	}
-
-	public Shell getShell() {
-		return styledShell;
-	}
-
-	public boolean isAlreadyOpened() {
-		return isAlreadyOpened;
-	}
-
-	public void setBackground(Color color) {
-		styledShell.setBackground(color);
-	}
-
-	public int getAlpha() {
-		return alpha;
-	}
-
-	public void setAlpha(int alpha) {
-		this.alpha = alpha;
-	}
-
-	public void hideShell(boolean value) {
-		if (true == value) {
-			setAlpha(styledShell, 0);
-		} else {
-			setAlpha(styledShell, alpha);
-		}
-	}
-
-	public String getText() {
-
-		return true == isAlive() ? styledShell.getText() : null;
-	}
-
-	public void setText(String string) {
-		if (true == isAlive()) {
-			styledShell.setText(string);
-		}
-	}
-
-	public boolean isUseCustomTrim() {
-		return useCustomTrim;
-	}
-
-	private UIFunctionsSWT getUIFunctions() {
-		if (null == uiFunctions) {
-			uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-			if (null == uiFunctions) {
-				throw new NullPointerException(
-						"An initialized instance of UIFunctionsSWT is required to create a LightBoxShell");
-			}
-		}
-		return uiFunctions;
-	}
-
-	private void setAlpha(Shell shell, int alpha) {
-		if (true == isAlphaSupported && null != shell) {
-			shell.setAlpha(alpha);
-		}
-	}
-
-	public Rectangle getBounds() {
-		return styledShell.getBounds();
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/components/widgets/BubbleButton.java b/org/gudy/azureus2/ui/swt/components/widgets/BubbleButton.java
deleted file mode 100644
index 7a27c27..0000000
--- a/org/gudy/azureus2/ui/swt/components/widgets/BubbleButton.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package org.gudy.azureus2.ui.swt.components.widgets;
-
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Composite;
-
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-
-/**
- * A button that uses the skin look-n-feel for a 'flat' button
- * 
- * This is intended to be used in a regular SWT container (outside of the skin instance) for when the look and feel
- * of the skin button is desired
- */
-
-public class BubbleButton
-	extends SkinButton
-{
-
-	private Image[] backgroundImages = new Image[3];
-
-	private Image[] backgroundImages_hover = new Image[3];
-
-	private Color[] foregroundColors = new Color[3];
-
-	public BubbleButton(Composite parent) {
-		super(parent);
-
-		final ImageLoader imageLoader = ImageLoader.getInstance();
-		
-		backgroundImages[0] = imageLoader.getImage("button_dialog_left");
-		backgroundImages[1] = imageLoader.getImage("button_dialog_center");
-		backgroundImages[2] = imageLoader.getImage("button_dialog_right");
-
-		backgroundImages_hover[0] = imageLoader.getImage("button_dialog_left-over");
-		backgroundImages_hover[1] = imageLoader.getImage("button_dialog_center-over");
-		backgroundImages_hover[2] = imageLoader.getImage("button_dialog_right-over");
-
-		foregroundColors[0] = ColorCache.getColor(parent.getDisplay(), 194, 194,
-				194);
-		foregroundColors[1] = ColorCache.getColor(parent.getDisplay(), 194, 194,
-				194);
-		foregroundColors[2] = ColorCache.getColor(parent.getDisplay(), 85, 85, 85);
-
-		setInset(new Inset(20, 20, 0, 0));
-
-		/*
-		 * Increase default font height by 1 so the text for this button is a little bit taller
-		 */
-		FontData[] fData = getFont().getFontData();
-		for (int i = 0; i < fData.length; i++) {
-			fData[i].height += 1;
-		}
-		final Font newFont = new Font(getDisplay(), fData);
-		setFont(newFont);
-		addDisposeListener(new DisposeListener() {
-
-			public void widgetDisposed(DisposeEvent e) {
-				if (null != newFont && false == newFont.isDisposed()) {
-					newFont.dispose();
-				}
-				imageLoader.releaseImage("button_dialog_left");
-				imageLoader.releaseImage("button_dialog_center");
-				imageLoader.releaseImage("button_dialog_right");
-				imageLoader.releaseImage("button_dialog_left-over");
-				imageLoader.releaseImage("button_dialog_center-over");
-				imageLoader.releaseImage("button_dialog_right-over");
-			}
-		});
-	}
-
-	public Image[] getBackgroundImages() {
-		return backgroundImages;
-	}
-
-	public Image[] getBackgroundImages_disabled() {
-		return null;
-	}
-
-	public Image[] getBackgroundImages_hover() {
-		return backgroundImages_hover;
-	}
-
-	public Color[] getForegroundColors() {
-		return foregroundColors;
-	}
-
-}
diff --git a/org/gudy/azureus2/ui/swt/components/widgets/Inset.java b/org/gudy/azureus2/ui/swt/components/widgets/Inset.java
deleted file mode 100644
index 6a30951..0000000
--- a/org/gudy/azureus2/ui/swt/components/widgets/Inset.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.gudy.azureus2.ui.swt.components.widgets;
-
-public class Inset
-{
-	public int top = 0;
-
-	public int bottom = 0;
-
-	public int left = 0;
-
-	public int right = 0;
-
-	public Inset(int left, int right, int top, int bottom) {
-		this.left = left;
-		this.right = right;
-		this.top = top;
-		this.bottom = bottom;
-
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/components/widgets/PaginationWidget.java b/org/gudy/azureus2/ui/swt/components/widgets/PaginationWidget.java
deleted file mode 100644
index 4fca91d..0000000
--- a/org/gudy/azureus2/ui/swt/components/widgets/PaginationWidget.java
+++ /dev/null
@@ -1,226 +0,0 @@
-package org.gudy.azureus2.ui.swt.components.widgets;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.gudy.azureus2.ui.swt.Utils;
-
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-
-/**
- * A simple pagination widget that displays a set of selectable graphic elements; each
- * one representing a page
- * 
- * To use just create the widget on a parent, set the page count, and add a <code>PageSelectionListener</code>
- * to be notified when the user clicks on a page.
- * 
- * @author khai
- *
- */
-public class PaginationWidget
-{
-	private Composite parent = null;
-
-	private Canvas canvas = null;
-
-	private int hSpacing = 3;
-
-	private int yOffset = 5;
-
-	private Rectangle[] pages = new Rectangle[1];
-
-	private int currentPage = 0;
-
-	private int height = 5;
-
-	private int width = 8;
-
-	private FormData fd;
-
-	private Color color_normal = null;
-
-	private Color color_selected = null;
-
-	private List listeners = new ArrayList();
-
-	private int itemsPerPage = 1;
-
-	private int itemsTotal = 0;
-
-	public PaginationWidget(Composite parent) {
-		if (null == parent || true == parent.isDisposed()) {
-			throw new IllegalArgumentException("parent can not be null or disposed");
-		}
-
-		this.parent = parent;
-
-		init();
-	}
-
-	private void init() {
-
-		canvas = new Canvas(parent, SWT.NONE);
-
-		parent.setLayout(new FormLayout());
-		fd = new FormData();
-		fd.top = new FormAttachment(0, 0);
-		fd.bottom = new FormAttachment(100, 0);
-		fd.left = new FormAttachment(0, 0);
-		fd.right = new FormAttachment(100, 0);
-		canvas.setLayoutData(fd);
-
-		color_selected = ColorCache.getColor(canvas.getDisplay(), 204, 204, 204);
-		color_normal = ColorCache.getColor(canvas.getDisplay(), 99, 99, 99);
-
-		canvas.addPaintListener(new PaintListener() {
-
-			public void paintControl(PaintEvent e) {
-				if (pages.length > 1) {
-
-					for (int i = 0; i < pages.length; i++) {
-						if (i == currentPage) {
-							e.gc.setBackground(color_selected);
-						} else {
-							e.gc.setBackground(color_normal);
-						}
-						e.gc.fillRectangle(pages[i]);
-					}
-				}
-			}
-		});
-
-		Listener listener = new Listener() {
-
-			public void handleEvent(Event event) {
-
-				if (event.type == SWT.MouseDown) {
-					for (int i = 0; i < pages.length; i++) {
-						if (pages[i].contains(event.x, event.y)) {
-							currentPage = i;
-							canvas.redraw();
-							notifyListeners(i);
-							break;
-						}
-					}
-				}
-				if (event.type == SWT.MouseMove) {
-					boolean pageFound = false;
-					for (int i = 0; i < pages.length; i++) {
-						if (pages[i].contains(event.x, event.y)) {
-							String tooltipText = getTooltip(i);
-							if (false == tooltipText.equals(canvas.getToolTipText())) {
-								canvas.setToolTipText(tooltipText);
-							}
-							canvas.setCursor(canvas.getDisplay().getSystemCursor(
-									SWT.CURSOR_HAND));
-							pageFound = true;
-							break;
-						}
-					}
-
-					if (false == pageFound) {
-						canvas.setCursor(null);
-						canvas.setToolTipText(null);
-					}
-				}
-			}
-		};
-
-		canvas.addListener(SWT.MouseDown, listener);
-		canvas.addListener(SWT.MouseMove, listener);
-
-	}
-
-	private String getTooltip(int pageIndex) {
-		pageIndex++;
-		int end = Math.min(pageIndex * itemsPerPage, itemsTotal);
-		int start = Math.max(pageIndex * itemsPerPage - (itemsPerPage - 1), 1);
-		return start + "-" + end + " of " + itemsTotal;
-	}
-
-	public void setPageCount(int pageCount) {
-		pages = new Rectangle[pageCount];
-
-		/*
-		 * First page
-		 */
-		pages[0] = new Rectangle(0, yOffset, width, height);
-
-		/*
-		 * Remaining pages
-		 */
-		int xOffset = width + hSpacing;
-		for (int i = 1; i < pages.length; i++) {
-			pages[i] = new Rectangle(xOffset, yOffset, width, height);
-			xOffset += width + hSpacing;
-		}
-
-		if (parent.getLayoutData() instanceof FormData) {
-			FormData pfd = (FormData) parent.getLayoutData();
-			pfd.width = pageCount * (hSpacing + width);
-		}
-		fd.width = pageCount * (hSpacing + width);
-		canvas.setSize(pageCount * (hSpacing + width), 16);
-
-		Utils.relayout(parent);
-	}
-
-	public interface PageSelectionListener
-	{
-		public void pageSelected(int pageNumber);
-	}
-
-	public void addPageSelectionListener(PageSelectionListener listener) {
-		if (false == listeners.contains(listener) && null != listener) {
-			listeners.add(listener);
-		}
-	}
-
-	private void notifyListeners(int selectedPage) {
-		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
-			PageSelectionListener listener = (PageSelectionListener) iterator.next();
-			listener.pageSelected(selectedPage);
-		}
-	}
-
-	public int getCurrentPage() {
-		return currentPage;
-	}
-
-	public void setCurrentPage(int currentPage) {
-		if (this.currentPage != currentPage) {
-			this.currentPage = currentPage;
-			canvas.redraw();
-		}
-	}
-
-	public int getItemsPerPage() {
-		return itemsPerPage;
-	}
-
-	public void setItemsPerPage(int itemsPerPage) {
-		this.itemsPerPage = itemsPerPage;
-	}
-
-	public int getItemsTotal() {
-		return itemsTotal;
-	}
-
-	public void setItemsTotal(int itemsTotal) {
-		this.itemsTotal = itemsTotal;
-	}
-
-}
diff --git a/org/gudy/azureus2/ui/swt/components/widgets/SkinButton.java b/org/gudy/azureus2/ui/swt/components/widgets/SkinButton.java
deleted file mode 100644
index 391efaa..0000000
--- a/org/gudy/azureus2/ui/swt/components/widgets/SkinButton.java
+++ /dev/null
@@ -1,379 +0,0 @@
-package org.gudy.azureus2.ui.swt.components.widgets;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseTrackAdapter;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
-
-public abstract class SkinButton
-	extends Canvas
-{
-
-	protected static String imagePath = "com/aelitis/azureus/ui/images/";
-
-	public static final int WIDGET_STATE_NORMAL = 0;
-
-	public static final int WIDGET_STATE_NOT_VISIBLE = 1;
-
-	public static final int WIDGET_STATE_DISABLED = 2;
-
-	public static final int WIDGET_STATE_HOVER = 3;
-
-	private int currentState = WIDGET_STATE_NORMAL;
-
-	private Image buttonImage = null;
-
-	private String buttonText = null;
-
-	private int alpha = 255;
-
-	private Inset inset = new Inset(0, 0, 0, 0);
-
-	private Color foregroundHover = null;
-
-	private Color foregroundDisabled = null;
-
-	private boolean enabled = true;
-
-	public SkinButton(Composite parent) {
-		this(parent, null, null);
-	}
-
-	public SkinButton(Composite parent, String buttonText) {
-		this(parent, buttonText, null);
-	}
-
-	public SkinButton(Composite parent, String buttonText, Image buttonImage) {
-		super(parent, SWT.DOUBLE_BUFFERED | SWT.INHERIT_DEFAULT);
-		this.buttonImage = buttonImage;
-		this.buttonText = buttonText;
-
-		init();
-	}
-
-	private void init() {
-		setCursor(Cursors.handCursor);
-		addPaintListener(new PaintListener() {
-
-			public void paintControl(PaintEvent e) {
-				try {
-					e.gc.setAntialias(SWT.ON);
-					e.gc.setTextAntialias(SWT.ON);
-					e.gc.setAlpha(alpha);
-					e.gc.setInterpolation(SWT.HIGH);
-				} catch (Exception ex) {
-					// ignore.. some of these may not be avail
-				}
-
-				/*
-				 * Paint background
-				 */
-
-				Image[] images = getCurrentBackgroundImages();
-				if (null != images) {
-					if (images.length != 3) {
-						/*
-						 * If all three images are not specified then just draw the first one
-						 */
-						if (null != images[0] && false == images[0].isDisposed()) {
-							ImageData iData = images[0].getImageData();
-							e.gc.drawImage(images[0], 0, 0, iData.width, iData.height, 0, 0,
-									iData.width, iData.height);
-						}
-					}
-					/*
-					 * Draw the left, right, and tile the middle images to fill the space in between
-					 */
-					else {
-
-						int leftOffset = 0;
-						int rightOffset = 0;
-
-						/*
-						 * Draw 'left' image as-is from the left;
-						 * this will be drawn on top of the tiled 'center' image above
-						 */
-						if (null != images[0] && false == images[0].isDisposed()) {
-							ImageData iData = images[0].getImageData();
-							e.gc.drawImage(images[0], 0, 0, iData.width, iData.height, 0, 0,
-									iData.width, iData.height);
-							leftOffset = iData.width;
-						}
-
-						/*
-						 * Draw 'right' image as-is on the right;
-						 * this will be drawn on top of the tiled 'center' image above
-						 */
-						if (null != images[2] && false == images[2].isDisposed()) {
-							ImageData iData = images[2].getImageData();
-							rightOffset = getSize().x - iData.width;
-
-							e.gc.drawImage(images[2], 0, 0, iData.width, iData.height,
-									rightOffset, 0, iData.width, iData.height);
-						}
-
-						/*
-						 * Tile 'center' image across the entire canvas 
-						 */
-						if (null != images[1] && false == images[1].isDisposed()) {
-							ImageData iData = images[1].getImageData();
-							int iterations = (rightOffset - leftOffset) / iData.width;
-							int roundingOverflow = (rightOffset - leftOffset)
-									- (iterations * iData.width);
-
-							for (int i = 0; i < iterations; i++) {
-								e.gc.drawImage(images[1], 0, 0, iData.width, iData.height,
-										leftOffset + (i * iData.width), 0, iData.width,
-										iData.height);
-							}
-
-							if (roundingOverflow > 0) {
-								e.gc.drawImage(images[1], 0, 0, roundingOverflow, iData.height,
-										leftOffset + (iterations * iData.width), 0,
-										roundingOverflow, iData.height);
-							}
-						}
-
-					}
-				}
-
-				/*
-				 * Paint the image if there is one
-				 */
-				int imageOffset = 0;
-				if (null != getImage() && false == getImage().isDisposed()) {
-					ImageData iData = getImage().getImageData();
-					e.gc.drawImage(getImage(), 0, 0, iData.width, iData.height,
-							inset.left, inset.top, iData.width, iData.height);
-					imageOffset = inset.left + iData.width;
-				}
-
-				/*
-				 * Paints the text if there is one
-				 */
-				if (null != getText()) {
-
-					if (currentState == WIDGET_STATE_DISABLED) {
-						if (null != getForegroundColors()[2]) {
-							e.gc.setForeground(getForegroundColors()[2]);
-						}
-					} else if (currentState == WIDGET_STATE_HOVER) {
-						if (null != getForegroundColors()[1]) {
-							e.gc.setForeground(getForegroundColors()[1]);
-						}
-					} else if (null != getForegroundColors()[0]) {
-						e.gc.setForeground(getForegroundColors()[0]);
-					} else {
-						e.gc.setForeground(getForeground());
-					}
-					if (imageOffset != 0) {
-						imageOffset += 6;
-						Point extent = e.gc.textExtent(getText());
-						e.gc.drawText(getText(), imageOffset, (getSize().y / 2)
-								- (extent.y / 2), SWT.DRAW_TRANSPARENT | SWT.DRAW_MNEMONIC);
-					} else {
-						Point extent = e.gc.textExtent(getText());
-						e.gc.drawText(getText(), (getSize().x / 2) - (extent.x / 2),
-								(getSize().y / 2) - (extent.y / 2), SWT.DRAW_TRANSPARENT | SWT.DRAW_MNEMONIC);
-					}
-				}
-			}
-		});
-
-		addMouseTrackListener(new MouseTrackAdapter() {
-
-			public void mouseEnter(MouseEvent e) {
-				if (currentState != WIDGET_STATE_DISABLED) {
-					if (currentState != WIDGET_STATE_HOVER) {
-						currentState = WIDGET_STATE_HOVER;
-						refreshVisuals();
-					}
-				}
-			}
-
-			public void mouseExit(MouseEvent e) {
-				if (currentState != WIDGET_STATE_DISABLED) {
-					if (currentState != WIDGET_STATE_NORMAL) {
-						currentState = WIDGET_STATE_NORMAL;
-						refreshVisuals();
-					}
-				}
-			}
-
-		});
-
-	}
-
-	/**
-	 * Computes the optimal size to fit either/or the image, text, and background; whichever is larger
-	 */
-	public Point computeSize(int hint, int hint2, boolean changed) {
-		Point backgroundExtent = new Point(0, 0);
-		Point imageExtent = new Point(0, 0);
-		Point textExtent = new Point(0, 0);
-
-		if (null != getImage()) {
-			imageExtent.x = getImage().getImageData().width;
-			imageExtent.y = getImage().getImageData().height;
-		}
-
-		if (null != getText()) {
-			GC gc = new GC(getDisplay());
-			textExtent = gc.textExtent(getText());
-			gc.dispose();
-		}
-
-		Image[] bgImages = getBackgroundImages();
-		if (null != bgImages) {
-			if (null != bgImages[0]) {
-				backgroundExtent.x = bgImages[0].getImageData().width;
-				backgroundExtent.y = bgImages[0].getImageData().height;
-			}
-			if (null != bgImages[1]) {
-				backgroundExtent.x += bgImages[1].getImageData().width;
-				backgroundExtent.y = bgImages[1].getImageData().height;
-			}
-			if (null != bgImages[2]) {
-				backgroundExtent.x += bgImages[2].getImageData().width;
-				backgroundExtent.y = bgImages[2].getImageData().height;
-			}
-
-		}
-
-		int maxHeight = Math.max(backgroundExtent.y, imageExtent.y + inset.top
-				+ inset.bottom);
-		maxHeight = Math.max(maxHeight, textExtent.y + inset.top + inset.bottom);
-
-		int maxWidth = Math.max(backgroundExtent.x, imageExtent.x + 6
-				+ textExtent.x + inset.left + inset.right);
-
-		maxWidth = Math.max(maxWidth, imageExtent.x + inset.left + inset.right);
-		maxWidth = Math.max(maxWidth, textExtent.x + inset.left + inset.right);
-
-		return new Point(maxWidth, maxHeight);
-	}
-
-	private Image[] getCurrentBackgroundImages() {
-		if (currentState == WIDGET_STATE_DISABLED) {
-			Image[] images = getBackgroundImages_disabled();
-			if (null != images && images.length > 0) {
-				return images;
-			}
-		} else if (currentState == WIDGET_STATE_HOVER) {
-			Image[] images = getBackgroundImages_hover();
-			if (null != images && images.length > 0) {
-				return images;
-			}
-		}
-
-		/*
-		 * Defaults to same background
-		 */
-		Image[] images = getBackgroundImages();
-		if (null != images && images.length > 0) {
-			return images;
-		}
-
-		return null;
-	}
-
-	public Image getImage() {
-		return buttonImage;
-	}
-
-	public void setImage(Image buttonImage) {
-		if (this.buttonImage != buttonImage) {
-			this.buttonImage = buttonImage;
-			refreshVisuals();
-		}
-	}
-
-	public String getText() {
-		return buttonText;
-	}
-
-	public void setText(String buttonText) {
-		if (this.buttonText != buttonText) {
-			this.buttonText = buttonText;
-			refreshVisuals();
-		}
-	}
-
-	public abstract Image[] getBackgroundImages();
-
-	public abstract Image[] getBackgroundImages_disabled();
-
-	public abstract Image[] getBackgroundImages_hover();
-
-	public abstract Color[] getForegroundColors();
-
-	public void setEnabled(boolean enabled) {
-		if (this.enabled != enabled) {
-			this.enabled = enabled;
-			super.setEnabled(enabled);
-			if (false == enabled) {
-				currentState = WIDGET_STATE_DISABLED;
-				alpha = 128;
-			} else {
-				currentState = WIDGET_STATE_NORMAL;
-				alpha = 255;
-			}
-			refreshVisuals();
-			update();
-		}
-	}
-
-	public boolean isEnabled() {
-		return enabled;
-	}
-
-	public Inset getInset() {
-		return inset;
-	}
-
-	public void setInset(Inset inset) {
-		if (this.inset != inset) {
-			this.inset = inset;
-			refreshVisuals();
-		}
-
-	}
-
-	public void refreshVisuals() {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				if (false == isDisposed()) {
-					redraw();
-				}
-			}
-		}, false);
-	}
-
-	public Color getForegroundHover() {
-		return foregroundHover;
-	}
-
-	public void setForegroundHover(Color foregroundHover) {
-		this.foregroundHover = foregroundHover;
-	}
-
-	public Color getForegroundDisabled() {
-		return foregroundDisabled;
-	}
-
-	public void setForegroundDisabled(Color foregroundDisabled) {
-		this.foregroundDisabled = foregroundDisabled;
-	}
-
-}
diff --git a/org/gudy/azureus2/ui/swt/components/widgets/SkinLinkLabel.java b/org/gudy/azureus2/ui/swt/components/widgets/SkinLinkLabel.java
deleted file mode 100644
index e04c66d..0000000
--- a/org/gudy/azureus2/ui/swt/components/widgets/SkinLinkLabel.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.gudy.azureus2.ui.swt.components.widgets;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
-
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-
-/**
- * A link label using the color specified in the skin and the style consistent with
- * a linked skin text object
- * 
- * This is intended to be used in a regular SWT container (outside of the skin instance) for when the look and feel
- * of the skin link label is desirable.
- */
-public class SkinLinkLabel
-{
-
-	private Label linkLabel = null;
-
-	private Color textLinkColor = null;
-
-	private Color textLinkColorHover = null;
-
-	public SkinLinkLabel(Composite parent, final String url) {
-		textLinkColor = ColorCache.getColor(parent.getDisplay(), 109, 165, 255);
-
-		textLinkColorHover = ColorCache.getColor(parent.getDisplay(), 179, 208, 255);
-
-		linkLabel = new Label(parent, SWT.NONE);
-		linkLabel.setForeground(textLinkColor);
-		linkLabel.setCursor(Cursors.handCursor);
-
-		if (null != url && url.length() > 0) {
-			linkLabel.setToolTipText(url);
-		}
-
-		Listener linkListener = new Listener() {
-			public void handleEvent(Event event) {
-				if (event.type == SWT.MouseDown) {
-					Utils.launch(url);
-				} else if (event.type == SWT.MouseEnter) {
-					linkLabel.setForeground(textLinkColorHover);
-				} else if (event.type == SWT.MouseExit) {
-					linkLabel.setForeground(textLinkColor);
-				}
-			}
-		};
-
-		linkLabel.addListener(SWT.MouseDown, linkListener);
-		linkLabel.addListener(SWT.MouseEnter, linkListener);
-		linkLabel.addListener(SWT.MouseExit, linkListener);
-
-	}
-
-	public Control getControl() {
-		return linkLabel;
-	}
-
-	public Font getFont() {
-		return linkLabel.getFont();
-	}
-
-	public void setFont(Font font) {
-		linkLabel.setFont(font);
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/config/StringListParameter.java b/org/gudy/azureus2/ui/swt/config/StringListParameter.java
index 0882c73..c927701 100644
--- a/org/gudy/azureus2/ui/swt/config/StringListParameter.java
+++ b/org/gudy/azureus2/ui/swt/config/StringListParameter.java
@@ -117,6 +117,11 @@ public class StringListParameter extends Parameter {
       	// @see org.eclipse.swt.widgets.Text#computeSize(int, int, boolean)
       	public Point computeSize(int wHint, int hHint, boolean changed) {
       		// List widget, at least on Windows, forces the preferred height
+      		
+      		if ( hHint == 0 && !isVisible()){
+    			return( new Point( 0, 0 ));
+    		}
+      		
       		Point pt = super.computeSize(wHint, hHint, changed);
       		
       		if (hHint == SWT.DEFAULT) {
diff --git a/org/gudy/azureus2/ui/swt/config/StringParameter.java b/org/gudy/azureus2/ui/swt/config/StringParameter.java
index f5e6677..8c45fe3 100644
--- a/org/gudy/azureus2/ui/swt/config/StringParameter.java
+++ b/org/gudy/azureus2/ui/swt/config/StringParameter.java
@@ -60,6 +60,10 @@ public class StringParameter extends Parameter{
     		// Text widget, at least on Windows, forces the preferred width
     		// to the width of the text inside of it
     		// Fix this by forcing to LayoutData's minWidth
+    		if ( hHint==0 && !isVisible()){
+    			
+    			return( new Point( 0, 0 ));
+    		}
     		Point pt = super.computeSize(wHint, hHint, changed);
     		
     		if (wHint == SWT.DEFAULT) {
@@ -70,6 +74,8 @@ public class StringParameter extends Parameter{
       			}
       		}
     		}
+    		
+ 
     		return pt;
     	}
     };
diff --git a/org/gudy/azureus2/ui/swt/config/generic/GenericIntParameter.java b/org/gudy/azureus2/ui/swt/config/generic/GenericIntParameter.java
index 3f335d8..27bd05f 100644
--- a/org/gudy/azureus2/ui/swt/config/generic/GenericIntParameter.java
+++ b/org/gudy/azureus2/ui/swt/config/generic/GenericIntParameter.java
@@ -46,7 +46,7 @@ public class GenericIntParameter
 
 	// OSX doesn't send selection events while typing, so we need to trigger save
 	// on focus out
-	private boolean bTriggerOnFocusOut = Constants.isOSX;
+	private boolean bTriggerOnFocusOut = Utils.isCarbon;
 
 	private Spinner spinner;
 
@@ -54,7 +54,7 @@ public class GenericIntParameter
 
 	private TimerEventPerformer timerEventSave;
 
-	private final boolean delayIntialSet = Constants.isOSX && System.getProperty("os.version", "").startsWith("10.6");
+	private final boolean delayIntialSet = Utils.isCarbon && System.getProperty("os.version", "").startsWith("10.6");
 
 	public GenericIntParameter(GenericParameterAdapter adapter,
 			Composite composite, final String name) {
diff --git a/org/gudy/azureus2/ui/swt/config/wizard/ConfigureWizard.java b/org/gudy/azureus2/ui/swt/config/wizard/ConfigureWizard.java
index f7c65dc..9e78c73 100644
--- a/org/gudy/azureus2/ui/swt/config/wizard/ConfigureWizard.java
+++ b/org/gudy/azureus2/ui/swt/config/wizard/ConfigureWizard.java
@@ -27,6 +27,8 @@ import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
 import org.gudy.azureus2.ui.swt.wizard.Wizard;
 
+import com.aelitis.azureus.ui.UserPrompterResultListener;
+
 /**
  * @author Olivier
  * 
@@ -77,17 +79,22 @@ public class ConfigureWizard extends Wizard {
 		try {
 			if (!completed
 					&& !COConfigurationManager.getBooleanParameter("Wizard Completed")) {
-				int result = MessageBoxShell.open(this.getWizardWindow(),
+				MessageBoxShell mb = new MessageBoxShell(
 						MessageText.getString("wizard.close.confirmation"),
 						MessageText.getString("wizard.close.message"), new String[] {
 							MessageText.getString("Button.yes"),
 							MessageText.getString("Button.no")
 						}, 0);
 
-				if (result == 1) {
-					COConfigurationManager.setParameter("Wizard Completed", true);
-					COConfigurationManager.save();
-				}
+				mb.open(new UserPrompterResultListener() {
+					public void prompterClosed(int result) {
+						if (result == 1) {
+							COConfigurationManager.setParameter("Wizard Completed", true);
+							COConfigurationManager.save();
+						}
+					}
+				});
+
 			}
 		} catch (Exception e) {
 			e.printStackTrace();
diff --git a/org/gudy/azureus2/ui/swt/debug/UIDebugGenerator.java b/org/gudy/azureus2/ui/swt/debug/UIDebugGenerator.java
index 3e0b966..f9b6b34 100644
--- a/org/gudy/azureus2/ui/swt/debug/UIDebugGenerator.java
+++ b/org/gudy/azureus2/ui/swt/debug/UIDebugGenerator.java
@@ -39,9 +39,11 @@ import org.gudy.azureus2.platform.PlatformManagerFactory;
 import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT.TriggerInThread;
 
 import com.aelitis.azureus.core.*;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 
 /**
  * @author TuxPaper
@@ -127,8 +129,8 @@ public class UIDebugGenerator
 		String message = entryWindow.getSubmittedInput();
 
 		if (message == null || message.length() == 0) {
-			Utils.openMessageBox(Utils.findAnyShell(), SWT.OK,
-					"UIDebugGenerator.message.cancel", (String[]) null);
+			new MessageBoxShell(SWT.OK, "UIDebugGenerator.message.cancel",
+					(String[]) null).open(null);
 			return;
 		}
 
@@ -174,7 +176,7 @@ public class UIDebugGenerator
 
 
 		try {
-			File outFile = new File(SystemProperties.getUserPath(), "debug.zip");
+			final File outFile = new File(SystemProperties.getUserPath(), "debug.zip");
 			if (outFile.exists()) {
 				outFile.delete();
 			}
@@ -238,19 +240,23 @@ public class UIDebugGenerator
 			out.close();
 
 			if (outFile.exists()) {
-				int result = Utils.openMessageBox(Utils.findAnyShell(), SWT.OK
-						| SWT.CANCEL | SWT.ICON_INFORMATION | SWT.APPLICATION_MODAL,
+				MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.CANCEL
+						| SWT.ICON_INFORMATION | SWT.APPLICATION_MODAL,
 						"UIDebugGenerator.complete", new String[] { outFile.toString() });
-
-				if (result == SWT.OK) {
-					try {
-						PlatformManagerFactory.getPlatformManager().showFile(
-								outFile.getAbsolutePath());
-					} catch (Exception e) {
-						// TODO Auto-generated catch block
-						e.printStackTrace();
+				mb.open(new UserPrompterResultListener() {
+					public void prompterClosed(int result) {
+						if (result == SWT.OK) {
+							try {
+								PlatformManagerFactory.getPlatformManager().showFile(
+										outFile.getAbsolutePath());
+							} catch (Exception e) {
+								// TODO Auto-generated catch block
+								e.printStackTrace();
+							}
+						}
 					}
-				}
+				});
+
 			}
 
 		} catch (IOException e) {
diff --git a/org/gudy/azureus2/ui/swt/donations/DonationWindow.java b/org/gudy/azureus2/ui/swt/donations/DonationWindow.java
index a0fd0cf..b785d32 100644
--- a/org/gudy/azureus2/ui/swt/donations/DonationWindow.java
+++ b/org/gudy/azureus2/ui/swt/donations/DonationWindow.java
@@ -35,6 +35,7 @@ import org.gudy.azureus2.core3.stats.transfer.StatsFactory;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.security.CryptoManagerFactory;
@@ -62,8 +63,7 @@ public class DonationWindow
 	public static void checkForDonationPopup() {
 		if (shell != null) {
 			if (DEBUG) {
-				Utils.openMessageBox(null, SWT.OK, "Donations Test",
-						"Already Open");
+				new MessageBoxShell(SWT.OK, "Donations Test", "Already Open").open(null);
 			}
 			return;
 		}
@@ -73,8 +73,8 @@ public class DonationWindow
 				"donations.donated", false);
 		if (alreadyDonated) {
 			if (DEBUG) {
-				Utils.openMessageBox(null, SWT.OK, "Donations Test",
-						"Already Donated! I like you.");
+				new MessageBoxShell(SWT.OK, "Donations Test",
+						"Already Donated! I like you.").open(null);
 			}
 			return;
 		}
@@ -97,16 +97,16 @@ public class DonationWindow
 					+ initialAskHours);
 			COConfigurationManager.save();
 			if (DEBUG) {
-				Utils.openMessageBox(null, SWT.OK, "Donations Test",
-						"Newbie. You're active for " + hours + ".");
+				new MessageBoxShell(SWT.OK, "Donations Test",
+						"Newbie. You're active for " + hours + ".").open(null);
 			}
 			return;
 		}
 
 		if (hours < nextAsk) {
 			if (DEBUG) {
-				Utils.openMessageBox(null, SWT.OK, "Donations Test", "Wait "
-						+ (nextAsk - hours) + ".");
+				new MessageBoxShell(SWT.OK, "Donations Test", "Wait "
+						+ (nextAsk - hours) + ".").open(null);
 			}
 			return;
 		}
@@ -115,9 +115,9 @@ public class DonationWindow
 				0);
 		if (minDate > 0 && minDate > SystemTime.getCurrentTime()) {
 			if (DEBUG) {
-				Utils.openMessageBox(null, SWT.OK, "Donation Test", "Wait "
+				new MessageBoxShell(SWT.OK, "Donation Test", "Wait "
 						+ ((SystemTime.getCurrentTime() - minDate) / 1000 / 3600 / 24)
-						+ " days");
+						+ " days").open(null);
 			}
 			return;
 		}
@@ -176,15 +176,17 @@ public class DonationWindow
 			}
 		});
 
-		try {
-			browser = new Browser(shell, Utils.getInitialBrowserStyle(SWT.NONE));
-		} catch (Throwable t) {
+		browser = Utils.createSafeBrowser(shell, SWT.NONE);
+		if (browser == null) {
 			shell.dispose();
 			return;
 		}
 
 		browser.addTitleListener(new TitleListener() {
 			public void changed(TitleEvent event) {
+				if (shell == null || shell.isDisposed()) {
+					return;
+				}
 				shell.setText(event.title);
 			}
 		});
@@ -193,6 +195,10 @@ public class DonationWindow
 			String last = null;
 
 			public void changed(StatusTextEvent event) {
+				if (shell == null || shell.isDisposed()) {
+					return;
+				}
+
 				String text = event.text.toLowerCase();
 				if (last != null && last.equals(text)) {
 					return;
@@ -273,12 +279,12 @@ public class DonationWindow
 									Debug.out("Page Didn't Load:" + url);
 									shell.dispose();
 									if (showNoLoad) {
-  									Utils.openMessageBox(shell, SWT.OK,
+										new MessageBoxShell(SWT.OK,
   											MessageText.getString("DonationWindow.noload.title"),
   											MessageText.getString("DonationWindow.noload.text",
 														new String[] {
 															url
-														}));
+														})).open(null);
 									}
 								}
 							});
diff --git a/org/gudy/azureus2/ui/swt/help/AboutWindow.java b/org/gudy/azureus2/ui/swt/help/AboutWindow.java
index 4206c98..c969145 100644
--- a/org/gudy/azureus2/ui/swt/help/AboutWindow.java
+++ b/org/gudy/azureus2/ui/swt/help/AboutWindow.java
@@ -25,9 +25,7 @@ import java.util.Properties;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.*;
@@ -39,8 +37,8 @@ import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.*;
+import org.gudy.azureus2.update.CorePatchLevel;
 
-import com.aelitis.azureus.core.versioncheck.VersionCheckClient;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
 /**
@@ -54,13 +52,24 @@ public class AboutWindow {
   static AEMonitor	class_mon	= new AEMonitor( "AboutWindow" );
   private static Shell instance;
 	private static Image imgSrc;
+	private static int paintColorTo = 0;
 
-  public static void show(final Display display) {
+  public static void show() {
+  	Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				_show();
+			}
+		});
+  }
+
+  private static void _show() {
     if(instance != null)
     {
         instance.open();
         return;
     }
+    
+    paintColorTo = 0;
 
     Properties properties = new Properties();
     try {
@@ -74,6 +83,7 @@ public class AboutWindow {
     final Shell window = ShellFactory.createMainShell((Constants.isOSX)
 				? SWT.DIALOG_TRIM : (SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL));
     Utils.setShellIcon(window);
+    final Display display = window.getDisplay();
 
     window.setText(MessageText.getString("MainWindow.about.title") + " " + Constants.AZUREUS_VERSION); //$NON-NLS-1$
     GridData gridData;
@@ -126,10 +136,27 @@ public class AboutWindow {
     label.setText(properties.getProperty("developers")); //$NON-NLS-1$ //$NON-NLS-2$
     label.setLayoutData(gridData = new GridData());
     
-    final Label labelImage = new Label(window, SWT.NONE);
-    labelImage.setImage(image);
+    final Canvas labelImage = new Canvas(window, SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND);
+    //labelImage.setImage(image);
     gridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+    Rectangle imgBounds = image.getBounds();
+    gridData.widthHint = imgBounds.width;
+    gridData.heightHint = imgBounds.height;
     labelImage.setLayoutData(gridData);
+    labelImage.addPaintListener(new PaintListener() {
+			public void paintControl(PaintEvent e) {
+				Rectangle boundsColor = imgSrc.getBounds();
+				if (paintColorTo > 0) {
+					e.gc.drawImage(imgSrc, 0, 0, paintColorTo, boundsColor.height, 0, 0, paintColorTo, boundsColor.height);
+				}
+				Rectangle imgBounds = image.getBounds();
+				if (imgBounds.width - paintColorTo - 1 > 0) {
+					e.gc.drawImage(image, 
+							paintColorTo + 1, 0, imgBounds.width - paintColorTo - 1, imgBounds.height, 
+							paintColorTo + 1, 0, imgBounds.width - paintColorTo - 1, imgBounds.height);
+				}
+			}
+		});
   
     Group gTranslators = new Group(window, SWT.NULL);
     GridLayout gl = new GridLayout();
@@ -172,7 +199,8 @@ public class AboutWindow {
 				+ System.getProperty("os.name") + " v"
 				+ System.getProperty("os.version") + ", "
 				+ System.getProperty("os.arch") + "\n"
-				+ Constants.APP_NAME.charAt(0) + Constants.AZUREUS_VERSION + " " + COConfigurationManager.getStringParameter("ui"));
+				+ Constants.APP_NAME.charAt(0) + Constants.AZUREUS_VERSION + "/" + CorePatchLevel.getCurrentPatchLevel() + " " 
+				+ COConfigurationManager.getStringParameter("ui"));
     txtSysInfo.setLayoutData(gridData = new GridData(GridData.FILL_BOTH));
     if (window.getCaret() != null)
     	window.getCaret().setVisible(false);
@@ -229,37 +257,28 @@ public class AboutWindow {
         }
     });
 
-    Thread updater =  new AEThread("Splash Screen Updater") {
-      public void runSupport() {        
+    AEThread2 updater =  new AEThread2("Splash Screen Updater", true) {
+      public void run() {        
         if(image == null || image.isDisposed())
           return;
         
-        final boolean finished[] = new boolean[1];
-        final int[] x = new int[1];
         final int maxX = image.getBounds().width;
         final int maxY = image.getBounds().height;
-        while(!finished[0]) {
+        while(paintColorTo < maxX) {
           if(image == null || image.isDisposed()) {
-            finished[0] = true;
+            paintColorTo = maxX;
             break;
           }
           if(display.isDisposed()) {
-            finished[0] = true;
+            paintColorTo = maxX;
             break;
           }
           Utils.execSWTThread(new AERunnable() {
             public void runSupport() {
               if(labelImage.isDisposed())
                 return;
-              GC gcImage = new GC(labelImage);
-              gcImage.setClipping(x[0],0,1,maxY);
-              gcImage.drawImage(imgSrc,0,0);
-              gcImage.dispose();
-              x[0]++;
-              if(x[0] >= maxX) {
-                finished[0] = true;
-                labelImage.setImage(imgSrc);
-              }
+              paintColorTo++;
+              labelImage.redraw(paintColorTo - 1, 0, 2, maxY, true);
             }
           });
           try {
@@ -294,7 +313,7 @@ public class AboutWindow {
   		new Display();
   		Colors.getInstance();
 			SWTThread.createInstance(null);
-			show(Display.getCurrent());
+			show();
 		} catch (SWTThreadAlreadyInstanciatedException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/Colors.java b/org/gudy/azureus2/ui/swt/mainwindow/Colors.java
index 9fda3a8..2f862c7 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/Colors.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/Colors.java
@@ -68,6 +68,7 @@ public class Colors implements ParameterListener {
   public static Color red;
   public static Color fadedRed;
   public static Color yellow;
+  public static Color fadedYellow;
   public static Color white;
   public static Color background;
   public static Color red_ConsoleView;
@@ -323,6 +324,7 @@ public class Colors implements ParameterListener {
 		red = ColorCache.getColor(display, 255, 0, 0);
 		fadedRed = ColorCache.getColor(display, 160, 96, 96);
 		yellow = ColorCache.getColor(display, 255, 255, 0);
+		fadedYellow = ColorCache.getColor(display, 255, 255, 221);
 		white = ColorCache.getColor(display, 255, 255, 255);
 		background = ColorCache.getColor(display, 248, 248, 248);
 		red_ConsoleView = ColorCache.getColor(display, 255, 192, 192);
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/IMenuConstants.java b/org/gudy/azureus2/ui/swt/mainwindow/IMenuConstants.java
index f9f34a1..a28f13e 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/IMenuConstants.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/IMenuConstants.java
@@ -31,11 +31,6 @@ public interface IMenuConstants
 	public static int FOR_AZ3 = 1 << 1;
 
 	/**
-	 * Bit mask for az3 advanced
-	 */
-	public static int FOR_AZ3_ADV = 1 << 2;
-
-	/**
 	 * A key used to store key/value pairs for menu ids;
 	 * currently used for setting the menu id for menus and menu items.
 	 * <p><b>NOTE:</b> This is not a localization key
@@ -56,8 +51,6 @@ public interface IMenuConstants
 
 	public static final String MENU_ID_VIEW = "MainWindow.menu.view";
 
-	public static final String MENU_ID_CONTENT_NETWORKS = "v3.MainWindow.menu.contentnetworks";
-
 	public static final String MENU_ID_TORRENT = "MainWindow.menu.torrent";
 
 	public static final String MENU_ID_TOOLS = "MainWindow.menu.tools";
@@ -120,6 +113,8 @@ public interface IMenuConstants
 
 	public static final String MENU_ID_ALL_PEERS = "MainWindow.menu.view.allpeers";
 
+	public static final String MENU_ID_CLIENT_STATS = "MainWindow.menu.view.clientstats";
+
 	public static final String MENU_ID_MY_TRACKERS = "MainWindow.menu.view.mytracker";
 
 	public static final String MENU_ID_MY_SHARES = "MainWindow.menu.view.myshares";
@@ -186,10 +181,6 @@ public interface IMenuConstants
 	
 	public static final String MENU_ID_COMMUNITY_WIKI = "MainWindow.menu.community.wiki";
 
-	public static final String MENU_ID_COMMUNITY_ADD_FRIENDS = "MainWindow.menu.community.add_friends";
-	
-	public static final String MENU_ID_PUBLISH = "v3.MainWindow.menu.publish";
-	
 	public static final String MENU_ID_HELP_SUPPORT = "MainWindow.menu.help.support";
 	
 	public static final String MENU_ID_DONATE = "MainWindow.menu.help.donate";
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/Initializer.java b/org/gudy/azureus2/ui/swt/mainwindow/Initializer.java
index 3991ffa..620829f 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/Initializer.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/Initializer.java
@@ -539,7 +539,7 @@ Initializer
   }
 
 	public void runInSWTThread() {
-  		String uiMode = UISwitcherUtil.openSwitcherWindow(false);
+  		String uiMode = UISwitcherUtil.calcUIMode();
   		
   		if (uiMode.equals("az3")) {
   			try {
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/MainMenu.java b/org/gudy/azureus2/ui/swt/mainwindow/MainMenu.java
index b5bb804..49ce854 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/MainMenu.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/MainMenu.java
@@ -31,6 +31,7 @@ import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.SystemProperties;
+import org.gudy.azureus2.ui.swt.Utils;
 
 /**
  * @author Olivier Chalouhi
@@ -186,9 +187,11 @@ public class MainMenu
 		 * No need for restart and exit on OSX in the File menu since it is moved to the gobla application
 		 * menu instead see org.gudy.azureus2.ui.swt.osx.CarbonUIEnhancer for detail about that menu
 		 */
-		if (false == Constants.isOSX) {
+		if (!Utils.isCarbon) {
 			MenuFactory.addSeparatorMenuItem(fileMenu);
 			MenuFactory.addRestartMenuItem(fileMenu);
+		}
+		if (!Constants.isOSX) {
 			MenuFactory.addExitMenuItem(fileMenu);
 		}
 
@@ -219,6 +222,7 @@ public class MainMenu
 			indent(MenuFactory.addViewToolbarMenuItem(viewMenu));
 			indent(MenuFactory.addTransferBarToMenu(viewMenu));
 			indent(MenuFactory.addAllPeersMenuItem(viewMenu));
+			indent(MenuFactory.addClientStatsMenuItem(viewMenu));
 			if (Constants.isCVSVersion()) {
 				indent(MenuFactory.addDetailedListMenuItem(viewMenu));
 			}
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/MainStatusBar.java b/org/gudy/azureus2/ui/swt/mainwindow/MainStatusBar.java
index 348e38d..01cff89 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/MainStatusBar.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/MainStatusBar.java
@@ -20,6 +20,7 @@
 package org.gudy.azureus2.ui.swt.mainwindow;
 
 import java.text.NumberFormat;
+import java.util.ArrayList;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CLabel;
@@ -103,6 +104,8 @@ public class MainStatusBar
 	private CLabel statusUp;
 
 	private Composite plugin_label_composite;
+	
+	private ArrayList<Runnable> listRunAfterInit = new ArrayList<Runnable>();
 
 	private Display display;
 
@@ -544,6 +547,22 @@ public class MainStatusBar
 		
 		uiFunctions.getUIUpdater().addUpdater(this);
 		
+		ArrayList<Runnable> list;
+		this_mon.enter();
+		try {
+			list = listRunAfterInit;
+			listRunAfterInit = null;
+		} finally {
+			this_mon.exit();
+		}
+		for (Runnable runnable : list) {
+			try {
+				runnable.run();
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+		
 		return statusBar;
 	}
 
@@ -580,36 +599,39 @@ public class MainStatusBar
 
 		} else if (secs_uptime - last_uptime > 15 * 60) {
 
-			CLabel feedback = createStatusEntry(new CLabelUpdater() {
+			createStatusEntry(new CLabelUpdater() {
 				public void update(CLabel label) {
 				}
-			});
-			
-			feedback.setText(MessageText.getString("statusbar.feedback"));
-
-			Listener feedback_listener = new Listener() {
-				public void handleEvent(Event e) {
 
-					String url = "feedback?" + Utils.getWidgetBGColorURLParam()
+				public void created(CLabel feedback) {
+					feedback.setText(MessageText.getString("statusbar.feedback"));
+					
+					Listener feedback_listener = new Listener() {
+						public void handleEvent(Event e) {
+							
+							String url = "feedback.start?" + Utils.getWidgetBGColorURLParam()
 							+ "&fromWeb=false&os.name=" + UrlUtils.encode(Constants.OSName)
 							+ "&os.version="
 							+ UrlUtils.encode(System.getProperty("os.version"))
 							+ "&java.version=" + UrlUtils.encode(Constants.JAVA_VERSION);
-
-					// Utils.launch( url );
-
-					UIFunctionsManagerSWT.getUIFunctionsSWT().viewURL(url, null, 600,
-							520, true, false);
+							
+							// Utils.launch( url );
+							
+							UIFunctionsManagerSWT.getUIFunctionsSWT().viewURL(url, null, 600,
+									520, true, false);
+						}
+					};
+					
+					feedback.setToolTipText(MessageText.getString("statusbar.feedback.tooltip"));
+					feedback.setCursor(Cursors.handCursor);
+					feedback.setForeground(Colors.blue);
+					feedback.addListener(SWT.MouseUp, feedback_listener);
+					feedback.addListener(SWT.MouseDoubleClick, feedback_listener);
+					
+					feedback.setVisible(true);
 				}
-			};
-			
-			feedback.setToolTipText(MessageText.getString("statusbar.feedback.tooltip"));
-			feedback.setCursor(Cursors.handCursor);
-			feedback.setForeground(Colors.blue);
-			feedback.addListener(SWT.MouseUp, feedback_listener);
-			feedback.addListener(SWT.MouseDoubleClick, feedback_listener);
+			});
 			
-			feedback.setVisible(true);
 		}
 	}
 
@@ -1146,6 +1168,7 @@ public class MainStatusBar
 
 	public static interface CLabelUpdater
 	{
+		public void created(CLabel label);
 		public void update(CLabel label);
 	}
 
@@ -1225,21 +1248,26 @@ public class MainStatusBar
 		}
 	}
 
-	public CLabel createStatusEntry(final CLabelUpdater updater) {
-		final CLabel[] result = new CLabel[1];
-		Utils.execSWTThread(new AERunnable() {
+	public void createStatusEntry(final CLabelUpdater updater) {
+		AERunnable r = new AERunnable() {
 			public void runSupport() {
-				try {
-					this_mon.enter();
-					result[0] = new UpdateableCLabel(plugin_label_composite, borderFlag,
-							updater);
-					result[0].setLayoutData(new GridData(GridData.FILL_BOTH));
-				} finally {
-					this_mon.exit();
-				}
+				UpdateableCLabel result = new UpdateableCLabel(plugin_label_composite, borderFlag,
+						updater);
+				result.setLayoutData(new GridData(GridData.FILL_BOTH));
+				updater.created(result);
 			}
-		}, false);
-		return result[0];
+		};
+		this_mon.enter();
+		try {
+			if (listRunAfterInit != null) {
+				listRunAfterInit.add(r);
+				return;
+			}
+		} finally {
+			this_mon.exit();
+		}
+
+		Utils.execSWTThread(r);
 	}
 
 	// =============================================================
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/MainWindow.java b/org/gudy/azureus2/ui/swt/mainwindow/MainWindow.java
index 06833b1..b81c5ec 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/MainWindow.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/MainWindow.java
@@ -68,6 +68,7 @@ import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
 import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
 import org.gudy.azureus2.ui.swt.sharing.progress.ProgressWindow;
 import org.gudy.azureus2.ui.swt.views.*;
+import org.gudy.azureus2.ui.swt.views.clientstats.ClientStatsView;
 import org.gudy.azureus2.ui.swt.views.stats.StatsView;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab;
@@ -154,6 +155,8 @@ public class MainWindow
 
 	private Item config;
 
+	private Item viewClientStats;
+	
 	private ConfigView config_view;
 
 	protected AEMonitor this_mon = new AEMonitor("MainWindow");
@@ -287,8 +290,8 @@ public class MainWindow
 
 			globalManager.loadExistingTorrentsNow(true);
 
-			COConfigurationManager.addParameterListener("config.style.useSIUnits",
-					this);
+			COConfigurationManager.addParameterListener("config.style.useSIUnits", this);
+			COConfigurationManager.addParameterListener("config.style.forceSIValues", this);
 
 			mytorrents = null;
 			my_tracker_tab = null;
@@ -598,6 +601,14 @@ public class MainWindow
 			});
 		}
 
+		if (!Constants.isSafeMode && COConfigurationManager.getBooleanParameter("Open Client Stats")) {
+			Utils.execSWTThreadLater(delay += delayInc, new Runnable() {
+				public void run() {
+					showClientStatsView();
+				}
+			});
+		}
+
 		COConfigurationManager.addAndFireParameterListener("IconBar.enabled",
 				new ParameterListener() {
 					public void parameterChanged(String parameterName) {
@@ -673,9 +684,7 @@ public class MainWindow
 			return;
 		}
 
-		// No tray access on OSX yet
-		boolean bEnableTray = COConfigurationManager.getBooleanParameter("Enable System Tray")
-				&& (!Constants.isOSX || SWT.getVersion() > 3300);
+		boolean bEnableTray = COConfigurationManager.getBooleanParameter("Enable System Tray");
 		boolean bPassworded = COConfigurationManager.getBooleanParameter("Password enabled");
 		boolean bStartMinimize = bEnableTray
 				&& (bPassworded || COConfigurationManager.getBooleanParameter("Start Minimized"));
@@ -819,6 +828,23 @@ public class MainWindow
 		refreshTorrentMenu();
 	}
 
+	protected void showClientStatsView() {
+		if (viewClientStats == null) {
+			ClientStatsView view = new ClientStatsView();
+			viewClientStats = mainTabSet.createTabItem(view, true);
+			mainTabSet.getView(viewClientStats).getComposite().addDisposeListener(
+					new DisposeListener() {
+						public void widgetDisposed(DisposeEvent e) {
+							viewClientStats = null;
+						}
+					});
+		} else {
+			mainTabSet.setFocus(viewClientStats);
+		}
+		refreshIconBar();
+		refreshTorrentMenu();
+	}
+
 	protected void showMultiOptionsView(DownloadManager[] managers) {
 		if (multi_options_tab != null) {
 			multi_options_tab.dispose();
@@ -975,7 +1001,9 @@ public class MainWindow
 					}
 
 					if (visible) {
-						shell.setMinimized(false);
+						if (shell.getMinimized()) {
+							shell.setMinimized(false);
+						}
 						if (!currentlyVisible
 								&& COConfigurationManager.getBooleanParameter("window.maximized")) {
 							shell.setMaximized(true);
@@ -1083,8 +1111,9 @@ public class MainWindow
 			shell.dispose();
 		}
 
-		COConfigurationManager.removeParameterListener("config.style.useSIUnits",
-				this);
+		COConfigurationManager.removeParameterListener("config.style.useSIUnits", this);
+		COConfigurationManager.removeParameterListener("config.style.forceSIValues", this);
+		
 		COConfigurationManager.removeParameterListener("Show Download Basket", this);
 
 		UIExitUtilsSWT.uiShutdown();
@@ -1208,7 +1237,7 @@ public class MainWindow
 			}
 		}
 
-		if (parameterName.equals("config.style.useSIUnits")) {
+		if (parameterName.equals("config.style.useSIUnits") || parameterName.equals("config.style.forceSIValues")) {
 			updateComponents();
 		}
 	}
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/MenuFactory.java b/org/gudy/azureus2/ui/swt/mainwindow/MenuFactory.java
index 5bf9ff2..3ba6a86 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/MenuFactory.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/MenuFactory.java
@@ -38,6 +38,8 @@ import org.gudy.azureus2.ui.swt.nat.NatTestWindow;
 import org.gudy.azureus2.ui.swt.pluginsinstaller.InstallPluginWizard;
 import org.gudy.azureus2.ui.swt.pluginsuninstaller.UnInstallPluginWizard;
 import org.gudy.azureus2.ui.swt.sharing.ShareUtils;
+import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.speedtest.SpeedTestWizard;
 import org.gudy.azureus2.ui.swt.update.UpdateMonitor;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
@@ -47,6 +49,7 @@ import org.gudy.azureus2.ui.swt.welcome.WelcomeWindow;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.vuzefile.VuzeFileComponent;
 import com.aelitis.azureus.core.vuzefile.VuzeFileHandler;
 import com.aelitis.azureus.ui.UIFunctions;
@@ -58,8 +61,6 @@ public class MenuFactory
 	implements IMenuConstants
 {
 
-	public static boolean isAZ3_ADV = COConfigurationManager.getBooleanParameter("v3.Start Advanced");
-
 	private static boolean isAZ3 = "az3".equalsIgnoreCase(COConfigurationManager.getStringParameter("ui"));
 
 	public static MenuItem createFileMenuItem(Menu menuParent) {
@@ -105,10 +106,6 @@ public class MenuFactory
 		return createTopLevelMenuItem(menuParent, MENU_ID_VIEW);
 	}
 
-	public static MenuItem createPublishMenuItem(Menu menuParent) {
-		return createTopLevelMenuItem(menuParent, MENU_ID_PUBLISH);
-	}
-
 	public static MenuItem createAdvancedMenuItem(Menu menuParent) {
 		return createTopLevelMenuItem(menuParent, MENU_ID_ADVANCED);
 	}
@@ -568,6 +565,17 @@ public class MenuFactory
 		});
 	}
 
+	public static MenuItem addClientStatsMenuItem(Menu menu) {
+		return addMenuItem(menu, MENU_ID_CLIENT_STATS, new Listener() {
+			public void handleEvent(Event e) {
+				UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+				if (uiFunctions != null) {
+					uiFunctions.openView(UIFunctions.VIEW_PEERS_STATS, null);
+				}
+			}
+		});
+	}
+
 	public static MenuItem addMyTrackerMenuItem(Menu menu) {
 		return addMenuItem(menu, MENU_ID_MY_TRACKERS, new Listener() {
 			public void handleEvent(Event e) {
@@ -685,7 +693,11 @@ public class MenuFactory
 	public static MenuItem addSpeedTestMenuItem(Menu menu) {
 		return addMenuItem(menu, MENU_ID_SPEED_TEST, new Listener() {
 			public void handleEvent(Event e) {
-				new SpeedTestWizard();
+				CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
+					public void azureusCoreRunning(AzureusCore core) {
+						new SpeedTestWizard();
+					}
+				});
 			}
 		});
 	}
@@ -904,7 +916,7 @@ public class MenuFactory
 	public static MenuItem addAboutMenuItem(Menu menu) {
 		return addMenuItem(menu, MENU_ID_ABOUT, new Listener() {
 			public void handleEvent(Event e) {
-				AboutWindow.show(getDisplay());
+				AboutWindow.show();
 			}
 		});
 	}
@@ -990,13 +1002,10 @@ public class MenuFactory
 
 							public void complete(UpdateCheckInstance instance) {
 								if (instance.getUpdates().length == 0) {
-									Utils.execSWTThread(new AERunnable() {
-										public void runSupport() {
-											Utils.openMessageBox(menu.getShell(),
-													SWT.ICON_INFORMATION | SWT.OK,
-													"window.update.noupdates", (String[]) null);
-										}
-									});
+									MessageBoxShell mb = new MessageBoxShell(
+											SWT.ICON_INFORMATION | SWT.OK,
+											"window.update.noupdates", (String[]) null);
+									mb.open(null);
 								}
 							}
 						});
@@ -1335,8 +1344,6 @@ public class MenuFactory
 		int keys = getEnablementKeys(widget);
 		if (keys <= 0) {
 			return true;
-		} else if (true == isAZ3_ADV) {
-			return ((keys & FOR_AZ3_ADV) != 0);
 		} else if (true == isAZ3) {
 			return ((keys & FOR_AZ3) != 0);
 		} else {
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/SWTThread.java b/org/gudy/azureus2/ui/swt/mainwindow/SWTThread.java
index 4ce2154..cfea6cc 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/SWTThread.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/SWTThread.java
@@ -22,29 +22,27 @@
 package org.gudy.azureus2.ui.swt.mainwindow;
 
 import java.lang.reflect.Constructor;
-import java.util.HashMap;
-import java.util.Map;
+import java.lang.reflect.Method;
 
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Monitor;
-import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.*;
 
-import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.platform.PlatformManagerFactory;
+import org.gudy.azureus2.ui.swt.UISwitcherListener;
+import org.gudy.azureus2.ui.swt.UISwitcherUtil;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
-import com.aelitis.azureus.ui.IUIIntializer;
+import com.aelitis.azureus.ui.*;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 
 /**
  * The main SWT Thread, the only one that should run any GUI code.
  */
 public class SWTThread {
-  private static final int	FREQ_PER_SEC_LIMIT = 10;
-  
   private static SWTThread instance;
   
   public static SWTThread getInstance() {
@@ -56,12 +54,6 @@ public class SWTThread {
       throw new SWTThreadAlreadyInstanciatedException();
     }
     
-    // set SWT specific config parameter defaults
-    
-    boolean bGTKTableBug_default = SWT.getPlatform().equals("gtk");
-  
-    COConfigurationManager.setBooleanDefault( "SWT_bGTKTableBug", bGTKTableBug_default );
-    
     	//Will only return on termination
     
     new SWTThread(initializer);
@@ -75,8 +67,6 @@ public class SWTThread {
   private Thread runner;
   private final IUIIntializer initializer;
   
-  private Map	freq_map = new HashMap();
-
 	private Monitor primaryMonitor;
   
   private 
@@ -86,6 +76,8 @@ public class SWTThread {
     
     this.initializer = app;
 		instance = this;
+    Display.setAppName(Constants.APP_NAME);
+
     try {
       display = Display.getCurrent();
 	  if ( display == null ){
@@ -127,8 +119,6 @@ public class SWTThread {
 			return;
 		}
     
-    Display.setAppName(Constants.APP_NAME);
-    
     primaryMonitor = display.getPrimaryMonitor();
     
     AEDiagnostics.addEvidenceGenerator(new AEDiagnosticsEvidenceGenerator() {
@@ -153,24 +143,88 @@ public class SWTThread {
 			}
 		});
     
-    if ( Constants.isOSX && SWT.getPlatform().equals("carbon") ){
-    	
-    		// use reflection here so we decouple generic SWT from OSX specific stuff to an extent
-    	
-    	 try{
-    	 	
-            Class ehancerClass = Class.forName("org.gudy.azureus2.ui.swt.osx.CarbonUIEnhancer");
-            
-            Constructor constructor = ehancerClass.getConstructor(new Class[]{});
-            
-            constructor.newInstance(new Object[] {});
+    UISwitcherUtil.addListener(new UISwitcherListener() {
+			public void uiSwitched(String ui) {
+				MessageBoxShell mb = new MessageBoxShell(
+						MessageText.getString("dialog.uiswitcher.restart.title"),
+						MessageText.getString("dialog.uiswitcher.restart.text"),
+						new String[] {
+							MessageText.getString("UpdateWindow.restart"),
+							MessageText.getString("UpdateWindow.restartLater"),
+						}, 0);
+				mb.open(new UserPrompterResultListener() {
+					public void prompterClosed(int result) {
+						if (result != 0) {
+							return;
+						}
+						UIFunctions uif = UIFunctionsManager.getUIFunctions();
+						if (uif != null) {
+							uif.dispose(true, false);
+						}
+					}
+				});
+			}
+		});
 
-        } catch (Exception e) {
-        	
-            Debug.printStackTrace(e);
-        }
-    }
-    
+		display.addListener(SWT.Activate, new Listener() {
+			public void handleEvent(Event event) {
+				UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
+				if (uif != null) {
+					uif.bringToFront(false);
+				}
+			}
+		});
+
+		if (Constants.isOSX) {
+			
+			// On Cocoa, we get a Close trigger on display.  Need to check if all
+			// platforms send this.
+			display.addListener(SWT.Close, new Listener() {
+				public void handleEvent(Event event) {
+					event.doit = UIFunctionsManager.getUIFunctions().dispose(false, false);
+				}
+			});
+
+			String platform = SWT.getPlatform();
+			// use reflection here so we decouple generic SWT from OSX specific stuff to an extent
+
+			if (platform.equals("carbon")) {
+				try {
+
+					Class<?> ehancerClass = Class.forName("org.gudy.azureus2.ui.swt.osx.CarbonUIEnhancer");
+
+					Constructor<?> constructor = ehancerClass.getConstructor(new Class[] {});
+
+					constructor.newInstance(new Object[] {});
+
+				} catch (Throwable e) {
+
+					Debug.printStackTrace(e);
+				}
+			} else if (platform.equals("cocoa")) {
+				try {
+
+					Class<?> ehancerClass = Class.forName("org.gudy.azureus2.ui.swt.osx.CocoaUIEnhancer");
+
+					Method mGetInstance = ehancerClass.getMethod("getInstance", new Class[0]);
+					Object claObj = mGetInstance.invoke(null, new Object[0] );
+
+					Method mHookAppMenu = claObj.getClass().getMethod("hookApplicationMenu", new Class[] {});
+					if (mHookAppMenu != null) {
+						mHookAppMenu.invoke(claObj, new Object[0]);
+					}
+
+					Method mHookDocOpen = claObj.getClass().getMethod("hookDocumentOpen", new Class[] {});
+					if (mHookDocOpen != null) {
+						mHookDocOpen.invoke(claObj, new Object[0]);
+					}
+					
+				} catch (Throwable e) {
+
+					Debug.printStackTrace(e);
+				}
+			}
+		}   
 
 		if (app != null) {
 			app.runInSWTThread();
@@ -190,18 +244,25 @@ public class SWTThread {
               display.sleep();
         }
         catch (Throwable e) {
-					if (Constants.isOSX && (e instanceof SWTException)
-							&& e.getMessage().endsWith(" is disposed")
-							&& (terminated || Debug.getStackTrace(e).indexOf("DropTarget") > 0)) {
+					if (terminated) {
 						Logger.log(new LogEvent(LogIDs.GUI,
-								"Weird non-critical display disposal in readAndDispatch"));
+								"Weird non-critical error after terminated in readAndDispatch: "
+										+ e.toString()));
 					} else {
-						// Must use printStackTrace() (no params) in order to get 
-						// "cause of"'s stack trace in SWT < 3119
-						if (SWT.getVersion() < 3119)
-							e.printStackTrace();
-						if (Constants.isCVSVersion()) {
-							Logger.log(new LogAlert(LogAlert.UNREPEATABLE,MessageText.getString("SWT.alert.erroringuithread"),e));
+						String stackTrace = Debug.getStackTrace(e);
+						if (Constants.isOSX 
+								&& stackTrace.indexOf("Device.dispose") > 0
+								&& stackTrace.indexOf("DropTarget") > 0) {
+							Logger.log(new LogEvent(LogIDs.GUI,
+									"Weird non-critical display disposal in readAndDispatch"));
+						} else {
+  						// Must use printStackTrace() (no params) in order to get 
+  						// "cause of"'s stack trace in SWT < 3119
+  						if (SWT.getVersion() < 3119)
+  							e.printStackTrace();
+  						if (Constants.isCVSVersion()) {
+  							Logger.log(new LogAlert(LogAlert.UNREPEATABLE,MessageText.getString("SWT.alert.erroringuithread"),e));
+  						}
 						}
 						
 					}
@@ -272,70 +333,6 @@ public class SWTThread {
 	public IUIIntializer getInitializer() {
 		return initializer;
 	}
-	
-	public void
-	limitFrequencyAsyncExec(
-		Object		owner,
-		Display		display,
-		AERunnable	target )
-	{
-		if ( display.isDisposed()){
-			
-			return;
-		}
-		
-		int	now = (int)( SystemTime.getCurrentTime()/1000 );
-		
-		boolean	do_it	= true;
-		
-		synchronized( freq_map ){
-			
-			if ( freq_map.size() > 1024 ){
-				
-				Debug.out( "Frequency map is overloaded - check your logic!!!!" );
-				
-			}else{
-				
-				int[]	data = (int[])freq_map.get( owner );
-			
-				if ( data == null ){
-					
-					data = new int[]{ now, 0 };
-					
-					freq_map.put( owner, data );
-				}
-				
-				if ( data[0] == now ){
-					
-					data[1]++;
-					
-					if ( data[1] > FREQ_PER_SEC_LIMIT ){
-						
-						do_it	= false;
-						
-						Debug.out( "SWT frequency limit exceeded for " + owner.getClass());
-					}
-				}else{
-					
-					data[0] = now;
-					data[1] = 1;
-				}
-			}
-		}
-		
-		if ( do_it ){
-			
-			display.asyncExec( target );
-		}
-	}
-	
-	public void removeLimitedFrequencyOwner(Object owner)
-	{
-		synchronized (freq_map)
-		{
-			freq_map.remove(owner);
-		}		
-	}
 
 	public Monitor getPrimaryMonitor() {
 		return primaryMonitor;
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/SelectableSpeedMenu.java b/org/gudy/azureus2/ui/swt/mainwindow/SelectableSpeedMenu.java
index aa3a004..f890bc3 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/SelectableSpeedMenu.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/SelectableSpeedMenu.java
@@ -33,6 +33,8 @@ import org.gudy.azureus2.core3.global.GlobalManagerStats;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.plugins.ui.UIInputReceiver;
+import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
 import org.gudy.azureus2.ui.swt.shells.SpeedScaleShell;
@@ -149,46 +151,44 @@ public class SelectableSpeedMenu {
 									: "MyTorrentsView.dialog.setNumber.download")
 						});
 
-				entryWindow.prompt();
-				if (!entryWindow.hasSubmittedInput()) {
-					return;
-				}
-				String sReturn = entryWindow.getSubmittedInput();
-
-				if (sReturn == null)
-					return;
-
-				int newSpeed;
-				try {
-					newSpeed = (int) (Double.valueOf(sReturn).doubleValue());
-				} catch (NumberFormatException er) {
-					MessageBox mb = new MessageBox(parent.getShell(),
-							SWT.ICON_ERROR | SWT.OK);
-					mb.setText(MessageText
-							.getString("MyTorrentsView.dialog.NumberError.title"));
-					mb.setMessage(MessageText
-							.getString("MyTorrentsView.dialog.NumberError.text"));
-
-					mb.open();
-					return;
-				}
-				
-			    if ( up_menu ){	   
-			    }
-			    
-                if ( up_menu ){
-                    
-                	String configAutoKey = 
-                		TransferSpeedValidator.getActiveAutoUploadParameter(globalManager);
-     
-                	COConfigurationManager.setParameter( configAutoKey, false );
-                }
-                
-                final int cValue = ((Integer)new TransferSpeedValidator(configKey, new Integer(newSpeed)).getValue()).intValue();
-                
-                COConfigurationManager.setParameter(configKey, cValue);
-                
-                COConfigurationManager.save();
+				entryWindow.prompt(new UIInputReceiverListener() {
+					public void UIInputReceiverClosed(UIInputReceiver entryWindow) {
+						if (!entryWindow.hasSubmittedInput()) {
+							return;
+						}
+						String sReturn = entryWindow.getSubmittedInput();
+
+						if (sReturn == null)
+							return;
+
+						int newSpeed;
+						try {
+							newSpeed = (int) (Double.valueOf(sReturn).doubleValue());
+						} catch (NumberFormatException er) {
+							MessageBox mb = new MessageBox(parent.getShell(), SWT.ICON_ERROR
+									| SWT.OK);
+							mb.setText(MessageText.getString("MyTorrentsView.dialog.NumberError.title"));
+							mb.setMessage(MessageText.getString("MyTorrentsView.dialog.NumberError.text"));
+
+							mb.open();
+							return;
+						}
+
+						if (up_menu) {
+
+							String configAutoKey = TransferSpeedValidator.getActiveAutoUploadParameter(globalManager);
+
+							COConfigurationManager.setParameter(configAutoKey, false);
+						}
+
+						final int cValue = ((Integer) new TransferSpeedValidator(configKey,
+								new Integer(newSpeed)).getValue()).intValue();
+
+						COConfigurationManager.setParameter(configKey, cValue);
+
+						COConfigurationManager.save();
+					}
+				});
 			}
 		});
     }
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/UIFunctionsImpl.java b/org/gudy/azureus2/ui/swt/mainwindow/UIFunctionsImpl.java
index ba47f46..1348027 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/UIFunctionsImpl.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/UIFunctionsImpl.java
@@ -26,6 +26,7 @@ import org.eclipse.swt.widgets.*;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.PluginView;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.minibar.AllTransfersBar;
 import org.gudy.azureus2.ui.swt.minibar.MiniBarManager;
@@ -39,12 +40,11 @@ import org.gudy.azureus2.ui.swt.views.IView;
 
 import com.aelitis.azureus.ui.UIFunctionsUserPrompter;
 import com.aelitis.azureus.ui.UIStatusTextClickListener;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 import com.aelitis.azureus.ui.common.updater.UIUpdater;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT;
 
-import org.gudy.azureus2.plugins.PluginView;
-
 /**
  * @author TuxPaper
  * @created Jul 12, 2006
@@ -349,6 +349,14 @@ public class UIFunctionsImpl
 		});
 	}
 
+	private void showClientStatsView() {
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				mainwindow.showClientStatsView();
+			}
+		});
+	}
+
 	private void showMultiOptionsView(final DownloadManager[] dms) {
 		Utils.execSWTThreadLater(0, new AERunnable() {
 			public void runSupport() {
@@ -401,20 +409,20 @@ public class UIFunctionsImpl
 	}
 
 	// @see com.aelitis.azureus.ui.UIFunctions#promptUser(java.lang.String, java.lang.String, java.lang.String[], int, java.lang.String, java.lang.String, boolean, int)
-	public int promptUser(String title, String text, String[] buttons,
+	public void promptUser(String title, String text, String[] buttons,
 			int defaultOption, String rememberID, String rememberText,
-			boolean rememberByDefault, int autoCloseInMS) {
-		return MessageBoxShell.open(getMainShell(), title, text, buttons,
+			boolean rememberByDefault, int autoCloseInMS, UserPrompterResultListener l) {
+		MessageBoxShell.open(getMainShell(), title, text, buttons,
 				defaultOption, rememberID, rememberText, rememberByDefault,
-				autoCloseInMS);
+				autoCloseInMS, l);
 	}
 
 	// @see com.aelitis.azureus.ui.UIFunctions#getUserPrompter(java.lang.String, java.lang.String, java.lang.String[], int)
 	public UIFunctionsUserPrompter getUserPrompter(String title, String text,
 			String[] buttons, int defaultOption) {
 
-		MessageBoxShell mb = new MessageBoxShell(getMainShell(), title, text,
-				buttons, defaultOption);
+		MessageBoxShell mb = new MessageBoxShell(title, text, buttons,
+				defaultOption);
 		return mb;
 	}
 
@@ -461,6 +469,10 @@ public class UIFunctionsImpl
 				showAllPeersView();
 				break;
 
+			case VIEW_PEERS_STATS:
+				showClientStatsView();
+				break;
+
 			case VIEW_CONFIG:
 				showConfig((datasource instanceof String) ? (String) datasource : null);
 				break;
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/ModePanel.java b/org/gudy/azureus2/ui/swt/maketorrent/ModePanel.java
index 3703327..e773eff 100644
--- a/org/gudy/azureus2/ui/swt/maketorrent/ModePanel.java
+++ b/org/gudy/azureus2/ui/swt/maketorrent/ModePanel.java
@@ -298,9 +298,7 @@ public class ModePanel extends AbstractWizardPanel {
 	    }
     });
     btnWebSeed.setSelection(((NewTorrentWizard) wizard).useWebSeed);
-    
-    btnWebSeed.setEnabled( tracker_type != NewTorrentWizard.TT_DECENTRAL);
-    
+        
     //Line:
     // include hashes for other networks (
 
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/WebSeedsEditor.java b/org/gudy/azureus2/ui/swt/maketorrent/WebSeedsEditor.java
index 7bef256..e3779f9 100644
--- a/org/gudy/azureus2/ui/swt/maketorrent/WebSeedsEditor.java
+++ b/org/gudy/azureus2/ui/swt/maketorrent/WebSeedsEditor.java
@@ -90,7 +90,7 @@ public class WebSeedsEditor {
   private void createWindow() {
     this.display = Display.getCurrent();
     this.shell = org.gudy.azureus2.ui.swt.components.shell.ShellFactory.createShell(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
-    Messages.setLanguageText(this.shell,"wizard.multitracker.edit.title");
+    Messages.setLanguageText(this.shell,"wizard.webseedseditor.edit.title");
     Utils.setShellIcon(shell);
     GridLayout layout = new GridLayout();
     layout.numColumns = 3;
@@ -152,7 +152,7 @@ public class WebSeedsEditor {
     
     Composite cButtons = new Composite(shell, SWT.NULL);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 2;
+    gridData.horizontalSpan = 3;
     cButtons.setLayoutData(gridData);
     GridLayout layoutButtons = new GridLayout();
     layoutButtons.numColumns = 3;
@@ -210,9 +210,11 @@ public class WebSeedsEditor {
 	    }
     });
     
+    shell.pack();
+
     Point size = shell.computeSize(400,SWT.DEFAULT);
     shell.setSize(size);
-    
+        
     Utils.centreWindow( shell );
     
     shell.open();
@@ -316,7 +318,7 @@ public class WebSeedsEditor {
           //The Group menu
            
           MenuItem item = new MenuItem(menu,SWT.NULL);
-          Messages.setLanguageText(item,"wizard.multitracker.edit.newtracker");
+          Messages.setLanguageText(item,"wizard.webseedseditor.edit.newseed");
           item.addListener(SWT.Selection, new Listener() {
             public void handleEvent(Event arg0) {
               TreeItem itemTracker = newTracker(treeItem,"http://");
diff --git a/org/gudy/azureus2/ui/swt/nat/NatTestWindow.java b/org/gudy/azureus2/ui/swt/nat/NatTestWindow.java
index 764fa89..ab7f0f1 100644
--- a/org/gudy/azureus2/ui/swt/nat/NatTestWindow.java
+++ b/org/gudy/azureus2/ui/swt/nat/NatTestWindow.java
@@ -90,7 +90,7 @@ public class NatTestWindow {
   public NatTestWindow() {
     serverTCPListenPort = COConfigurationManager.getIntParameter( "TCP.Listen.Port" );
     
-    final Shell shell = ShellFactory.createShell(Utils.findAnyShell(), SWT.BORDER | SWT.TITLE | SWT.CLOSE);        
+    final Shell shell = ShellFactory.createMainShell(SWT.BORDER | SWT.TITLE | SWT.CLOSE);        
     shell.setText(MessageText.getString("configureWizard.nat.title"));
     Utils.setShellIcon(shell);
 
diff --git a/org/gudy/azureus2/ui/swt/networks/SWTNetworkSelection.java b/org/gudy/azureus2/ui/swt/networks/SWTNetworkSelection.java
index 261c38a..27c53b0 100644
--- a/org/gudy/azureus2/ui/swt/networks/SWTNetworkSelection.java
+++ b/org/gudy/azureus2/ui/swt/networks/SWTNetworkSelection.java
@@ -42,6 +42,7 @@ import org.gudy.azureus2.core3.util.AESemaphore;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 
 
@@ -77,7 +78,7 @@ SWTNetworkSelection
 		final classifierDialog[]	dialog = new classifierDialog[1];
 		
 		try{
-			display.asyncExec(
+			Utils.execSWTThread(
 				new AERunnable()
 				{
 					public void
@@ -120,12 +121,12 @@ SWTNetworkSelection
 			
 			if ( display.isDisposed()){
 				
-				sem.release();
+				sem.releaseForever();
 				
 				return;
 			}
 			
-	 		shell = new Shell (display,SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+	 		shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
 	 	
 	 		Utils.setShellIcon(shell);
 	 		
@@ -249,6 +250,12 @@ SWTNetworkSelection
 			Utils.centreWindow( shell );
 
 			shell.open ();   
+			
+			while (!shell.isDisposed()) {
+				if (display != null && !display.isDisposed() && !display.readAndDispatch()) {
+					display.sleep();
+				}
+			}
 		}
    
 		protected void
@@ -277,7 +284,7 @@ SWTNetworkSelection
 	 		}
 	 		
 	 		shell.dispose();
-	 		sem.release();
+	 		sem.releaseForever();
 	 	}
 	 	
 	 	protected String[]
diff --git a/org/gudy/azureus2/ui/swt/nico/testOSX.java b/org/gudy/azureus2/ui/swt/nico/testOSX.java
deleted file mode 100644
index 53b40b6..0000000
--- a/org/gudy/azureus2/ui/swt/nico/testOSX.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Created on 25 juin 2003
- * Copyright (C) 2003, 2004, 2005, 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *  
- */
-package org.gudy.azureus2.ui.swt.nico;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ShellAdapter;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.MessageBox;
-import org.eclipse.swt.widgets.Shell;
-import org.gudy.azureus2.core3.util.Debug;
-
-/**
- * @author Olivier
- *  
- */
-public class testOSX extends  Object{
-  
-  private Display display;
-  private Shell mainWindow;
- 
-
-  public testOSX() {
-
-    //The Main Window
-    display = new Display();
-    mainWindow = new Shell(display, SWT.RESIZE | SWT.BORDER | SWT.CLOSE | SWT.MAX | SWT.MIN);
-    mainWindow.setText("Test OSX"); //$NON-NLS-1$
-    
-    /*Listener printer = new Listener() { 
-    	public void handleEvent(Event evt) { 
-    		System.out.println("-->" + evt.type); 
-    	}
-    };
-    mainWindow.addListener(SWT.Close,printer);
-    mainWindow.addListener(SWT.Dispose,printer);
-    mainWindow.addListener(SWT.KeyDown,printer);
-    mainWindow.addListener(SWT.KeyUp,printer);
-    */
-      
-    mainWindow.open();
-    //mainWindow.forceActive();
-    
-    /*
-    mainWindow.addDisposeListener(new DisposeListener() {
-    	public void widgetDisposed(DisposeEvent arg0) {
-    		System.out.println("NICO disposelistener 002\n");
-    		if (mainWindow != null) {
-    			System.out.println("NICO disposelistener 002a\n");
-    			mainWindow.removeDisposeListener(this);
-    			System.out.println("NICO disposelistener 002b\n");
-    			dispose();
-    			System.out.println("NICO disposelistener 002c\n");
-    		}
-    		System.out.println("NICO disposelistener 003\n");
-    	}      
-    });
-    */
-
-    mainWindow.addShellListener(new ShellAdapter() {
-      public void shellClosed(ShellEvent event) {
-        if(getExitConfirmation()) {
-          dispose();
-        } else {
-          event.doit = false;
-        }
-      }
-    });
-  }
-
-
-  public void waitForClose() {
-  	while (!mainWindow.isDisposed()) {
-  		try {
-  			if (!display.readAndDispatch())
-  				display.sleep();
-  		}
-  		catch (Exception e) {
-  			Debug.printStackTrace( e );
-  		}
-  	}
-  	display.dispose();
-  }
-  
-  public static void main(String args[]) {	
-    testOSX mw = new testOSX();
-    mw.waitForClose();
-  }
-
-	
-
-  public void dispose() {
-    if(mainWindow != null && ! mainWindow.isDisposed())
-      mainWindow.dispose();
-  }
-
-  /**
-   * @return true, if the user choosed OK in the exit dialog
-   *
-   * @author Rene Leonhardt
-   */
-  private boolean getExitConfirmation() {
-    MessageBox mb = new MessageBox(mainWindow, SWT.ICON_WARNING | SWT.YES | SWT.NO);
-    mb.setText("Confirm");
-    mb.setMessage("Do you really want to exit?");
-    if(mb.open() == SWT.YES)
-      return true;
-    return false;
-  }
-  
-   
-
-
-}
diff --git a/org/gudy/azureus2/ui/swt/osx/CarbonUIEnhancer.java b/org/gudy/azureus2/ui/swt/osx/CarbonUIEnhancer.java
index c3fbc7c..049f6d5 100644
--- a/org/gudy/azureus2/ui/swt/osx/CarbonUIEnhancer.java
+++ b/org/gudy/azureus2/ui/swt/osx/CarbonUIEnhancer.java
@@ -30,6 +30,9 @@ import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
 import org.gudy.azureus2.ui.swt.nat.NatTestWindow;
 import org.gudy.azureus2.ui.swt.speedtest.SpeedTestWizard;
 
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
 import com.apple.cocoa.application.NSApplication;
@@ -288,7 +291,7 @@ public class CarbonUIEnhancer
 							return OS.noErr;
 						}
 						case kHICommandAbout:
-							AboutWindow.show(display);
+							AboutWindow.show();
 							return OS.noErr;
 						case kHICommandRestart: {
 							UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
@@ -566,7 +569,7 @@ public class CarbonUIEnhancer
 			OS.AECountItems(aeDesc, count);
 			//System.out.println("COUNT: " + count[0]);
 			if (count[0] > 0) {
-				String[] fileNames = new String[count[0]];
+				final String[] fileNames = new String[count[0]];
 				int maximumSize = 80; // size of FSRef
 				int dataPtr = OS.NewPtr(maximumSize);
 				int[] aeKeyword = new int[1];
@@ -580,18 +583,16 @@ public class CarbonUIEnhancer
 						int dirUrl = OS.CFURLCreateFromFSRef(OS.kCFAllocatorDefault, fsRef);
 						int dirString = OS.CFURLCopyFileSystemPath(dirUrl,
 								OS.kCFURLPOSIXPathStyle);
-						OS.CFRelease(dirUrl);
 						int length = OS.CFStringGetLength(dirString);
 						char[] buffer = new char[length];
 						CFRange range = new CFRange();
 						range.length = length;
 						OS.CFStringGetCharacters(dirString, range, buffer);
-						OS.CFRelease(dirString);
 						fileNames[i] = new String(buffer);
-					}
-
-					if (OS.AEGetNthPtr(aeDesc, i + 1, typeText, aeKeyword, typeCode,
-							dataPtr, maximumSize, actualSize) == OS.noErr) {
+						OS.CFRelease(dirString);
+						OS.CFRelease(dirUrl);
+					} else if (OS.AEGetNthPtr(aeDesc, i + 1, typeText, aeKeyword, typeCode,
+							dataPtr, 2048, actualSize) == OS.noErr) {
 						byte[] urlRef = new byte[actualSize[0]];
 						memmove(urlRef, dataPtr, actualSize[0]);
 						fileNames[i] = new String(urlRef);
@@ -600,7 +601,11 @@ public class CarbonUIEnhancer
 					//System.out.println(fileNames[i]);
 				}
 
-				TorrentOpener.openTorrents(fileNames);
+				AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+					public void azureusCoreRunning(AzureusCore core) {
+						TorrentOpener.openTorrents(fileNames);
+					}
+				});
 			}
 
 			return OS.noErr;
diff --git a/org/gudy/azureus2/ui/swt/osx/CocoaUIEnhancer.java b/org/gudy/azureus2/ui/swt/osx/CocoaUIEnhancer.java
new file mode 100644
index 0000000..092c18b
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/osx/CocoaUIEnhancer.java
@@ -0,0 +1,844 @@
+package org.gudy.azureus2.ui.swt.osx;
+
+import java.lang.reflect.*;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.internal.C;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Shell;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.config.wizard.ConfigureWizard;
+import org.gudy.azureus2.ui.swt.help.AboutWindow;
+import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
+import org.gudy.azureus2.ui.swt.nat.NatTestWindow;
+import org.gudy.azureus2.ui.swt.speedtest.SpeedTestWizard;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+
+/**
+ * You can exclude this file (or this whole path) for non OSX builds
+ * 
+ * Hook some Cocoa specific abilities:
+ * - App->About        <BR>
+ * - App->Preferences  <BR>
+ * - App->Exit         <BR>
+ * <BR>
+ * - OpenDocument  (possible limited to only files?) <BR>
+ *
+ * This code was influenced by the
+ * <a href="http://www.transparentech.com/opensource/cocoauienhancer">
+ * CocoaUIEnhancer</a>, which was influenced by the 
+ * <a href="http://www.simidude.com/blog/2008/macify-a-swt-application-in-a-cross-platform-way/">
+ * CarbonUIEnhancer from Agynami</a>.
+ * 
+ * Both cocoa implementations are modified from 
+ * <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.ui.cocoa/src/org/eclipse/ui/internal/cocoa/CocoaUIEnhancer.java">
+ * org.eclipse.ui.internal.cocoa.CocoaUIEnhancer</a>
+ */
+public class CocoaUIEnhancer
+{
+	private static final boolean DEBUG = false;
+
+	private static Object /*Callback*/ callBack3;
+
+	private static long callBack3Addr;
+
+	private static Object /*Callback*/ callBack4;
+
+	private static long callBack4Addr;
+
+	private static CocoaUIEnhancer instance;
+
+	private static final int kAboutMenuItem = 0;
+
+	private static final int kPreferencesMenuItem = 2;
+
+	private static final int kServicesMenuItem = 4;
+
+	// private static final int kHideApplicationMenuItem = 6;
+
+	// private static final int kQuitMenuItem = 10;
+
+	//private static int NSWindowCloseButton = 0;
+
+	//private static int NSWindowDocumentIconButton = 4;
+
+	//private static int NSWindowMiniaturizeButton = 1;
+
+	private static int NSWindowToolbarButton = 3;
+
+	//private static int NSWindowZoomButton = 2;
+
+	private static long sel_aboutMenuItemSelected_;
+
+	private static long sel_application_openFile_;
+
+	private static long sel_application_openFiles_;
+
+	private static long sel_preferencesMenuItemSelected_;
+
+	private static long sel_toolbarButtonClicked_;
+
+	private static long sel_restartMenuSelected_;
+
+	private static long sel_wizardMenuSelected_;
+
+	private static long sel_natMenuSelected_;
+
+	private static long sel_speedMenuSelected_;
+
+	static final byte[] SWT_OBJECT = {
+		'S',
+		'W',
+		'T',
+		'_',
+		'O',
+		'B',
+		'J',
+		'E',
+		'C',
+		'T',
+		'\0'
+	};
+
+	private long delegateIdSWTApplication;
+
+	private long delegateJniRef;
+
+	private Object delegate;
+
+	private static Class<?> osCls = classForName("org.eclipse.swt.internal.cocoa.OS");
+	private static Class<?> nsmenuCls = classForName("org.eclipse.swt.internal.cocoa.NSMenu");
+	private static Class<?> nsmenuitemCls = classForName("org.eclipse.swt.internal.cocoa.NSMenuItem");
+	private static Class<?> nsapplicationCls = classForName("org.eclipse.swt.internal.cocoa.NSApplication");
+	private static Class<?> nsarrayCls = classForName("org.eclipse.swt.internal.cocoa.NSArray");
+	private static Class<?> nsstringCls = classForName("org.eclipse.swt.internal.cocoa.NSString");
+	private static Class<?> swtmenuitemCls = classForName("org.eclipse.swt.internal.cocoa.SWTMenuItem");
+	private static Class<?> nsidCls = classForName("org.eclipse.swt.internal.cocoa.id");
+	private static Class<?> nsautoreleasepoolCls = classForName("org.eclipse.swt.internal.cocoa.NSAutoreleasePool");
+	private static Class<?> nsworkspaceCls = classForName("org.eclipse.swt.internal.cocoa.NSWorkspace");
+	private static Class<?> nsimageCls = classForName("org.eclipse.swt.internal.cocoa.NSImage");
+	private static Class<?> nssizeCls = classForName("org.eclipse.swt.internal.cocoa.NSSize");
+
+	static {
+		Class<CocoaUIEnhancer> clazz = CocoaUIEnhancer.class;
+		Class<?> callbackCls = classForName("org.eclipse.swt.internal.Callback");
+
+		try {
+			Method mGetAddress = callbackCls.getMethod("getAddress", new Class[0]);
+			Constructor<?> consCallback = callbackCls.getConstructor(new Class<?>[] {
+				Object.class,
+				String.class,
+				int.class
+			});
+			//callBack3 = new Callback(clazz, "actionProc", 3);
+			callBack3 = consCallback.newInstance(new Object[] {
+				clazz,
+				"actionProc",
+				3
+			});
+			Object object = mGetAddress.invoke(callBack3, (Object[]) null);
+			callBack3Addr = convertToLong(object);
+			if (callBack3Addr == 0) {
+				SWT.error(SWT.ERROR_NO_MORE_CALLBACKS);
+			}
+
+			//callBack4 = new Callback(clazz, "actionProc", 4);
+			callBack4 = consCallback.newInstance(new Object[] {
+				clazz,
+				"actionProc",
+				4
+			});
+			object = mGetAddress.invoke(callBack4, (Object[]) null);
+			callBack4Addr = convertToLong(object);
+			if (callBack4Addr == 0) {
+				SWT.error(SWT.ERROR_NO_MORE_CALLBACKS);
+			}
+		} catch (Throwable e) {
+			Debug.out(e);
+		}
+	}
+
+	static int actionProc(int id, int sel, int arg0) {
+		if (DEBUG) {
+			System.err.println("id=" + id + ";sel=" + sel);
+		}
+
+		if (sel == sel_aboutMenuItemSelected_) {
+			AboutWindow.show();
+		} else if (sel == sel_restartMenuSelected_) {
+			UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+			if (uiFunctions != null) {
+				uiFunctions.dispose(true, false);
+			}
+		} else if (sel == sel_wizardMenuSelected_) {
+			new ConfigureWizard(false);
+		} else if (sel == sel_natMenuSelected_) {
+			new NatTestWindow();
+		} else if (sel == sel_speedMenuSelected_) {
+			new SpeedTestWizard();
+		} else if (sel == sel_toolbarButtonClicked_) {
+			try {
+				Field fldsel_window = osCls.getField("sel_window");
+				Object windowId = invoke(osCls, "objc_msgSend", new Object[] {
+					wrapPointer(arg0),
+					fldsel_window.get(null)
+				});
+				final Shell shellAffected = (Shell) invoke(Display.class,
+						Display.getCurrent(), "findWidget", new Object[] {
+							windowId
+						});
+
+				Utils.execSWTThread(new AERunnable() {
+					public void runSupport() {
+						int type;
+						Long l = (Long) shellAffected.getData("OSX.ToolBarToggle");
+						if (l == null || l.longValue() == 0) {
+							type = SWT.Collapse;
+						} else {
+							type = SWT.Expand;
+						}
+
+						Event event = new Event();
+						event.type = type;
+						event.display = shellAffected.getDisplay();
+						event.widget = shellAffected;
+						shellAffected.notifyListeners(type, event);
+
+						shellAffected.setData("OSX.ToolBarToggle", new Long(
+								type == SWT.Collapse ? 1 : 0));
+					}
+				});
+			} catch (Throwable t) {
+				Debug.out(t);
+			}
+
+		} else if (sel == sel_preferencesMenuItemSelected_) {
+			UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+			if (uiFunctions != null) {
+				uiFunctions.openView(UIFunctions.VIEW_CONFIG, null);
+			}
+		}
+		return 0;
+	}
+
+	static int /*long*/actionProc(int /*long*/id, int /*long*/sel,
+			int /*long*/arg0, int /*long*/arg1)
+			throws Throwable {
+		if (DEBUG) {
+			System.err.println("actionProc 4 " + id + "/" + sel);
+		}
+		Display display = Display.getCurrent();
+		if (display == null)
+			return 0;
+
+		if (sel == sel_application_openFile_) {
+			Constructor<?> conNSString = nsstringCls.getConstructor(new Class[] {
+				int.class
+			});
+			Object file = conNSString.newInstance(arg1);
+			String fileString = (String) invoke(file, "getString");
+			if (DEBUG) {
+				System.err.println("OMG GOT OpenFile " + fileString);
+			}
+			fileOpen(new String[] {
+				fileString
+			});
+		} else if (sel == sel_application_openFiles_) {
+			Constructor<?> conNSArray = nsarrayCls.getConstructor(new Class[] {
+				int.class
+			});
+			Constructor<?> conNSString = nsstringCls.getConstructor(new Class[] {
+				nsidCls
+			});
+
+			Object arrayOfFiles = conNSArray.newInstance(arg1);
+			int count = ((Number) invoke(arrayOfFiles, "count")).intValue();
+
+			String[] files = new String[count];
+			for (int i = 0; i < count; i++) {
+				Object fieldId = invoke(nsarrayCls, arrayOfFiles, "objectAtIndex",
+						new Object[] {
+							i
+						});
+				Object nsstring = conNSString.newInstance(fieldId);
+				files[i] = (String) invoke(nsstring, "getString");
+
+				if (DEBUG) {
+					System.err.println("OMG GOT OpenFiles " + files[i]);
+				}
+			}
+			fileOpen(files);
+		}
+		return 0;
+	}
+
+	private static Class<?> classForName(String classname) {
+		try {
+			Class<?> cls = Class.forName(classname);
+			return cls;
+		} catch (ClassNotFoundException e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+	private static long convertToLong(Object object) {
+		if (object instanceof Integer) {
+			Integer i = (Integer) object;
+			return i.longValue();
+		}
+		if (object instanceof Long) {
+			Long l = (Long) object;
+			return l.longValue();
+		}
+		return 0;
+	}
+
+	protected static void fileOpen(final String[] files) {
+		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+			public void azureusCoreRunning(AzureusCore core) {
+				TorrentOpener.openTorrents(files);
+			}
+		});
+	}
+
+	public static CocoaUIEnhancer getInstance() {
+		if (instance == null) {
+			try {
+				instance = new CocoaUIEnhancer();
+			} catch (Throwable e) {
+				Debug.out(e);
+			}
+		}
+		return instance;
+	}
+
+	private static Object invoke(Class<?> clazz, Object target,
+			String methodName, Object[] args) {
+		try {
+			Class<?>[] signature = new Class<?>[args.length];
+			for (int i = 0; i < args.length; i++) {
+				Class<?> thisClass = args[i].getClass();
+				if (thisClass == Integer.class)
+					signature[i] = int.class;
+				else if (thisClass == Long.class)
+					signature[i] = long.class;
+				else if (thisClass == Byte.class)
+					signature[i] = byte.class;
+				else if (thisClass == Boolean.class)
+					signature[i] = boolean.class;
+				else
+					signature[i] = thisClass;
+			}
+			Method method = clazz.getMethod(methodName, signature);
+			return method.invoke(target, args);
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+	private static Object invoke(Class<?> clazz, Object target,
+			String methodName, Class[] signature, Object[] args) {
+		try {
+			Method method = clazz.getMethod(methodName, signature);
+			return method.invoke(target, args);
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+	private static Object invoke(Class<?> clazz, String methodName, Object[] args) {
+		return invoke(clazz, null, methodName, args);
+	}
+
+	private static Object invoke(Object obj, String methodName) {
+		return invoke(obj, methodName, (Class<?>[]) null, (Object[]) null);
+	}
+
+	private static Object invoke(Object obj, String methodName,
+			Class<?>[] paramTypes, Object... arguments) {
+		try {
+			Method m = obj.getClass().getMethod(methodName, paramTypes);
+			return m.invoke(obj, arguments);
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+	private static long registerName(Class<?> osCls, String name)
+			throws IllegalArgumentException, SecurityException,
+			IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+		Object object = invoke(osCls, "sel_registerName", new Object[] {
+			name
+		});
+		return convertToLong(object);
+	}
+
+	////////////////////////////////////////////////////////////
+
+	private static Object wrapPointer(long value) {
+		Class<?> PTR_CLASS = C.PTR_SIZEOF == 8 ? long.class : int.class;
+		if (PTR_CLASS == long.class)
+			return new Long(value);
+		else
+			return new Integer((int) value);
+	}
+
+	private CocoaUIEnhancer()
+			throws Throwable {
+
+		// Instead of creating a new delegate class in objective-c,
+		// just use the current SWTApplicationDelegate. An instance of this
+		// is a field of the Cocoa Display object and is already the target
+		// for the menuItems. So just get this class and add the new methods
+		// to it.
+		Object delegateObjSWTApplication = invoke(osCls, "objc_lookUpClass",
+				new Object[] {
+					"SWTApplicationDelegate"
+				});
+		delegateIdSWTApplication = convertToLong(delegateObjSWTApplication);
+
+		// This doesn't feel right, but it works
+		Class<?> swtapplicationdelegateCls = classForName("org.eclipse.swt.internal.cocoa.SWTApplicationDelegate");
+		delegate = swtapplicationdelegateCls.newInstance();
+		Object delegateAlloc = invoke(delegate, "alloc");
+		invoke(delegateAlloc, "init");
+		Object delegateIdObj = nsidCls.getField("id").get(delegate);
+		delegateJniRef = ((Number) invoke(osCls, "NewGlobalRef", new Class<?>[] {
+			Object.class
+		}, new Object[] {
+			CocoaUIEnhancer.this
+		})).longValue();
+		if (delegateJniRef == 0)
+			SWT.error(SWT.ERROR_NO_HANDLES);
+		//OS.object_setInstanceVariable(delegate.id, SWT_OBJECT, delegateJniRef);
+		invoke(osCls, "object_setInstanceVariable", new Object[] {
+			delegateIdObj,
+			SWT_OBJECT,
+			wrapPointer(delegateJniRef)
+		});
+	}
+
+	/**
+	 * Hook the given Listener to the Mac OS X application Quit menu and the IActions to the About
+	 * and Preferences menus.
+	 * 
+	 * @param display
+	 *            The Display to use.
+	 * @param quitListener
+	 *            The listener to invoke when the Quit menu is invoked.
+	 * @param aboutAction
+	 *            The action to run when the About menu is invoked.
+	 * @param preferencesAction
+	 *            The action to run when the Preferences menu is invoked.
+	 */
+	public void hookApplicationMenu() {
+		Display display = Display.getCurrent();
+		try {
+			// Initialize the menuItems.
+			initialize();
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
+		}
+
+		// Schedule disposal of callback object
+		display.disposeExec(new Runnable() {
+			public void run() {
+				invoke(callBack3, "dispose");
+				callBack3 = null;
+				invoke(callBack4, "dispose");
+				callBack4 = null;
+
+				if (delegateJniRef != 0) {
+					//OS.DeleteGlobalRef(delegateJniRef);
+					invoke(osCls, "DeleteGlobalRef", new Object[] {
+						wrapPointer(delegateJniRef)
+					});
+					delegateJniRef = 0;
+				}
+
+				if (delegate != null) {
+					invoke(delegate, "release");
+					delegate = null;
+				}
+			}
+		});
+	}
+
+	public void hookDocumentOpen()
+			throws Throwable {
+
+		if (sel_application_openFile_ == 0) {
+			sel_application_openFile_ = registerName(osCls, "application:openFile:");
+		}
+		invoke(osCls, "class_addMethod", new Object[] {
+			wrapPointer(delegateIdSWTApplication),
+			wrapPointer(sel_application_openFile_),
+			wrapPointer(callBack4Addr),
+			"@:@:@"
+		});
+
+		if (sel_application_openFiles_ == 0) {
+			sel_application_openFiles_ = registerName(osCls, "application:openFiles:");
+		}
+		invoke(osCls, "class_addMethod", new Object[] {
+			wrapPointer(delegateIdSWTApplication),
+			wrapPointer(sel_application_openFiles_),
+			wrapPointer(callBack4Addr),
+			"@:@:@"
+		});
+	}
+
+	private void initialize()
+			throws Exception {
+
+
+		// Register names in objective-c.
+		if (sel_preferencesMenuItemSelected_ == 0) {
+			sel_preferencesMenuItemSelected_ = registerName(osCls,
+					"preferencesMenuItemSelected:");
+			sel_aboutMenuItemSelected_ = registerName(osCls, "aboutMenuItemSelected:");
+			sel_restartMenuSelected_ = registerName(osCls, "restartMenuItemSelected:");
+			sel_natMenuSelected_ = registerName(osCls, "natMenuItemSelected:");
+			sel_speedMenuSelected_ = registerName(osCls, "speedMenuItemSelected:");
+			sel_wizardMenuSelected_ = registerName(osCls, "wizardMenuItemSelected:");
+		}
+
+		// Add the action callbacks for Preferences and About menu items.
+		invoke(osCls, "class_addMethod", new Object[] {
+			wrapPointer(delegateIdSWTApplication),
+			wrapPointer(sel_preferencesMenuItemSelected_),
+			wrapPointer(callBack3Addr),
+			"@:@"
+		});
+		invoke(osCls, "class_addMethod", new Object[] {
+			wrapPointer(delegateIdSWTApplication),
+			wrapPointer(sel_aboutMenuItemSelected_),
+			wrapPointer(callBack3Addr),
+			"@:@"
+		});
+		invoke(osCls, "class_addMethod", new Object[] {
+			wrapPointer(delegateIdSWTApplication),
+			wrapPointer(sel_restartMenuSelected_),
+			wrapPointer(callBack3Addr),
+			"@:@"
+		});
+		invoke(osCls, "class_addMethod", new Object[] {
+			wrapPointer(delegateIdSWTApplication),
+			wrapPointer(sel_wizardMenuSelected_),
+			wrapPointer(callBack3Addr),
+			"@:@"
+		});
+		invoke(osCls, "class_addMethod", new Object[] {
+			wrapPointer(delegateIdSWTApplication),
+			wrapPointer(sel_speedMenuSelected_),
+			wrapPointer(callBack3Addr),
+			"@:@"
+		});
+		invoke(osCls, "class_addMethod", new Object[] {
+			wrapPointer(delegateIdSWTApplication),
+			wrapPointer(sel_natMenuSelected_),
+			wrapPointer(callBack3Addr),
+			"@:@"
+		});
+
+		// Get the Mac OS X Application menu.
+		Object sharedApplication = invoke(nsapplicationCls, "sharedApplication");
+		Object mainMenu = invoke(sharedApplication, "mainMenu");
+		Object mainMenuItem = invoke(nsmenuCls, mainMenu, "itemAtIndex",
+				new Object[] {
+					wrapPointer(0)
+				});
+		Object appMenu = invoke(mainMenuItem, "submenu");
+
+		// Create the About <application-name> menu command
+		Object aboutMenuItem = invoke(nsmenuCls, appMenu, "itemAtIndex",
+				new Object[] {
+					wrapPointer(kAboutMenuItem)
+				});
+
+		// Enable the Preferences menuItem.
+		Object prefMenuItem = invoke(nsmenuCls, appMenu, "itemAtIndex",
+				new Object[] {
+					wrapPointer(kPreferencesMenuItem)
+				});
+		invoke(nsmenuitemCls, prefMenuItem, "setEnabled", new Object[] {
+			true
+		});
+
+		Object servicesMenuItem = invoke(nsmenuCls, appMenu, "itemAtIndex",
+				new Object[] {
+					wrapPointer(kServicesMenuItem)
+				});
+		invoke(nsmenuitemCls, servicesMenuItem, "setEnabled", new Object[] {
+			false
+		});
+
+		// Set the action to execute when the About or Preferences menuItem is invoked.
+		//
+		// We don't need to set the target here as the current target is the SWTApplicationDelegate
+		// and we have registerd the new selectors on it. So just set the new action to invoke the
+		// selector.
+		invoke(nsmenuitemCls, prefMenuItem, "setAction", new Object[] {
+			wrapPointer(sel_preferencesMenuItemSelected_)
+		});
+		invoke(nsmenuitemCls, aboutMenuItem, "setAction", new Object[] {
+			wrapPointer(sel_aboutMenuItemSelected_)
+		});
+
+		// Add other menus
+		Object menuId = appMenu.getClass().getField("id").get(appMenu);
+		boolean isAZ3 = "az3".equalsIgnoreCase(COConfigurationManager.getStringParameter("ui"));
+
+		if (!isAZ3) {
+			// add Wizard, NAT Test, Speed Test
+
+			addMenuItem(menuId, 5, (int) sel_wizardMenuSelected_,
+					MessageText.getString("MainWindow.menu.file.configure").replaceAll(
+							"&", ""));
+
+			addMenuItem(menuId, 6, (int) sel_natMenuSelected_, MessageText.getString(
+					"MainWindow.menu.tools.nattest").replaceAll("&", ""));
+
+			addMenuItem(menuId, 7, (int) sel_speedMenuSelected_,
+					MessageText.getString("MainWindow.menu.tools.speedtest").replaceAll(
+							"&", ""));
+
+		}
+
+		int numOfItems = ((Number) invoke(appMenu, "numberOfItems")).intValue();
+
+		Object sep = invoke(osCls, "objc_msgSend", new Object[] {
+			osCls.getField("class_NSMenuItem").get(null),
+			osCls.getField("sel_separatorItem").get(null)
+		});
+		invoke(osCls, "objc_msgSend", new Object[] {
+			sep,
+			osCls.getField("sel_retain").get(null)
+		});
+		//OS.objc_msgSend(menuId, OS.sel_insertItem_atIndex_, sep, numOfItems - 1);
+		invoke(osCls, "objc_msgSend", new Object[] {
+			menuId,
+			osCls.getField("sel_insertItem_atIndex_").get(null),
+			sep,
+			numOfItems - 1
+		});
+
+		numOfItems++;
+
+		addMenuItem(menuId, numOfItems - 1, (int) sel_restartMenuSelected_,
+				MessageText.getString("MainWindow.menu.file.restart").replaceAll("&",
+						""));
+	}
+
+	private void addMenuItem(Object menuId, int index, int selector, String title) {
+		try {
+			//NSMenuItem nsItem = (NSMenuItem) new SWTMenuItem().alloc();
+			Object oSWTMenuItem = swtmenuitemCls.newInstance();
+			Object nsItem = invoke(oSWTMenuItem, "alloc");
+
+			Object nsStrTitle = invoke(nsstringCls, "stringWith", new Object[] {
+				title
+			});
+			Object nsStrEmpty = invoke(nsstringCls, "stringWith", new Object[] {
+				""
+			});
+			invoke(nsmenuitemCls, nsItem, "initWithTitle", new Object[] {
+				nsStrTitle,
+				0,
+				nsStrEmpty
+			});
+			invoke(nsItem, "setTarget", new Class<?>[] {
+				nsidCls
+			}, new Object[] {
+				delegate
+			});
+			invoke(nsmenuitemCls, nsItem, "setAction", new Object[] {
+				wrapPointer(selector)
+			});
+
+			//OS.objc_msgSend(menuId, OS.sel_insertItem_atIndex_, nsItem.id, index);
+			invoke(osCls, "objc_msgSend", new Object[] {
+				menuId,
+				osCls.getField("sel_insertItem_atIndex_").get(null),
+				nsmenuitemCls.getField("id").get(nsItem),
+				index
+			});
+		} catch (Throwable e) {
+			Debug.out(e);
+		}
+	}
+
+	private Object invoke(Class<?> cls, String methodName) {
+		return invoke(cls, methodName, (Class<?>[]) null, (Object[]) null);
+	}
+
+	private Object invoke(Class<?> cls, String methodName, Class<?>[] paramTypes,
+			Object... arguments) {
+		try {
+			Method m = cls.getMethod(methodName, paramTypes);
+			return m.invoke(null, arguments);
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
+		}
+	}
+
+	public void registerToolbarToggle(Shell shell)
+			throws Throwable {
+
+		if (sel_toolbarButtonClicked_ == 0) {
+			sel_toolbarButtonClicked_ = registerName(osCls, "toolbarButtonClicked:");
+		}
+
+		invoke(osCls, "class_addMethod", new Object[] {
+			wrapPointer(delegateIdSWTApplication),
+			wrapPointer(sel_toolbarButtonClicked_),
+			wrapPointer(callBack3Addr),
+			"@:@"
+		});
+
+		Class<?> nstoolbarCls = classForName("org.eclipse.swt.internal.cocoa.NSToolbar");
+		Class<?> nsbuttonCls = classForName("org.eclipse.swt.internal.cocoa.NSButton");
+
+		//NSToolbar dummyBar = new NSToolbar();
+		Object dummyBar = nstoolbarCls.newInstance();
+		//dummyBar.alloc();
+		invoke(dummyBar, "alloc");
+		//dummyBar.initWithIdentifier(NSString.stringWith("SWTToolbar"));
+		Object nsStrDummyToolbar = invoke(nsstringCls, "stringWith", new Object[] {
+			"SWTToolbar"
+		});
+		invoke(dummyBar, "initWithIdentifier", new Class<?>[] {
+			nsstringCls
+		}, new Object[] {
+			nsStrDummyToolbar
+		});
+		//dummyBar.setVisible(false);
+		invoke(dummyBar, "setVisible", new Class<?>[] {
+			boolean.class
+		}, new Object[] {
+			Boolean.FALSE
+		});
+
+		// reflect me
+		//NSWindow nsWindow = shell.view.window();
+		Object view = shell.getClass().getField("view").get(shell);
+		Object nsWindow = invoke(view, "window");
+		//nsWindow.setToolbar(dummyBar);
+		invoke(nsWindow, "setToolbar", new Class<?>[] {
+			nstoolbarCls
+		}, new Object[] {
+			dummyBar
+		});
+		//nsWindow.setShowsToolbarButton(true);
+		invoke(nsWindow, "setShowsToolbarButton", new Class<?>[] {
+			boolean.class
+		}, new Object[] {
+			Boolean.TRUE
+		});
+
+		//NSButton toolbarButton = nsWindow.standardWindowButton(NSWindowToolbarButton);
+		Object toolbarButton = invoke(nsWindow, "standardWindowButton",
+				new Class<?>[] {
+					int.class
+				}, new Object[] {
+					new Integer(NSWindowToolbarButton)
+				});
+
+		//toolbarButton.setTarget(delegate);
+		invoke(toolbarButton, "setTarget", new Class[] {
+			nsidCls
+		}, new Object[] {
+			delegate
+		});
+
+		//OS.objc_msgSend(this.id, OS.sel_setTarget_, anObject != null ? anObject.id : 0);
+		//invoke(osCls, "objc_msgSend", new Object[] {
+		//	toolbarButton.getClass().getField("id").get(toolbarButton),
+		//	osCls.getField("sel_setTarget_").get(null),
+		//	wrapPointer(delegateIdSWTApplication)
+		//});
+
+		//toolbarButton.setAction((int) sel_toolbarButtonClicked_);
+		invoke(nsbuttonCls, toolbarButton, "setAction", new Object[] {
+			wrapPointer(sel_toolbarButtonClicked_)
+		});
+	}
+
+	// from Program.getImageData, except returns bigger images
+	public static Image getFileIcon (String path, int imageWidthHeight) {
+		Object pool = null;
+		try {
+			//NSAutoreleasePool pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+			pool = nsautoreleasepoolCls.newInstance();
+			Object delegateAlloc = invoke(pool, "alloc");
+			invoke(delegateAlloc, "init");
+
+			//NSWorkspace workspace = NSWorkspace.sharedWorkspace();
+			Object workspace = invoke(nsworkspaceCls, "sharedWorkspace", new Object[] {});
+			//NSString fullPath = NSString.stringWith(path);
+			Object fullPath = invoke(nsstringCls, "stringWith", new Object[] {
+				path
+			});
+			if (fullPath != null) {
+				// SWT also had a :
+				// fullPath = workspace.fullPathForApplication(NSString.stringWith(name));
+				// which might be handy someday, but for now, full path works
+
+				//NSImage nsImage = workspace.iconForFile(fullPath);
+				Object nsImage = invoke(workspace, "iconForFile", new Class[] {
+					nsstringCls
+				}, new Object[] {
+					fullPath
+				});
+				if (nsImage != null) {
+					//NSSize size = new NSSize();
+					Object size = nssizeCls.newInstance();
+					//size.width = size.height = imageWidthHeight;
+					nssizeCls.getField("width").set(size, imageWidthHeight);
+					nssizeCls.getField("height").set(size, imageWidthHeight);
+					//nsImage.setSize(size);
+					invoke(nsImage, "setSize", new Class[] {
+						nssizeCls
+					}, new Object[] {
+						size
+					});
+					//nsImage.retain();
+					invoke(nsImage, "retain");
+					//Image image = Image.cocoa_new(Display.getCurrent(), SWT.BITMAP, nsImage);
+					Image image = (Image) invoke(Image.class, null, "cocoa_new",
+							new Class[] {
+								Device.class,
+								int.class,
+								nsimageCls
+							}, new Object[] {
+								Display.getCurrent(),
+								SWT.BITMAP,
+								nsImage
+							});
+				return image;
+				}
+			}
+		} catch (Throwable t) {
+			Debug.printStackTrace(t);
+		} finally {
+			if (pool != null) {
+				invoke(pool, "release");
+			}
+		}
+		return null;
+	}
+
+}
diff --git a/org/gudy/azureus2/ui/swt/plugins/UISWTInstance.java b/org/gudy/azureus2/ui/swt/plugins/UISWTInstance.java
index 36545a9..f5cd95c 100644
--- a/org/gudy/azureus2/ui/swt/plugins/UISWTInstance.java
+++ b/org/gudy/azureus2/ui/swt/plugins/UISWTInstance.java
@@ -24,6 +24,8 @@ package org.gudy.azureus2.ui.swt.plugins;
 
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.ui.UIInstance;
 import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
@@ -283,4 +285,14 @@ public interface UISWTInstance extends UIInstance {
 	 */
 	public void openConfig(BasicPluginConfigModel model);
 
+	/**
+	 * Creates a SWT Shell, ensuring Vuze knows about it (ie. Icon, "Window" menu)
+	 *  
+	 * @param style
+	 * @return
+	 * 
+	 * @since 4.2.0.9
+	 */
+	Shell createShell(int style);
+
 }
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginConfigImpl.java b/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginConfigImpl.java
index 3c2370b..72e1b8f 100644
--- a/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginConfigImpl.java
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginConfigImpl.java
@@ -253,10 +253,19 @@ BasicPluginConfigImpl
 										param.removeListener( this );								
 									}else{
 										
-										String hyperlink = ((HyperlinkParameterImpl)param).getHyperlink();
+										final String hyperlink = ((HyperlinkParameterImpl)param).getHyperlink();
 										
 										if (hyperlink != null) {
-											LinkLabel.updateLinkedLabel(f_label, hyperlink);
+											
+											Utils.execSWTThread(
+												new Runnable()
+												{
+													public void
+													run()
+													{
+														LinkLabel.updateLinkedLabel(f_label, hyperlink);
+													}
+												});
 										}
 									}
 								}
@@ -643,6 +652,8 @@ BasicPluginConfigImpl
 				    	
 				    	con.setVisible(false);
 				    	
+				    	con.setSize( 0, 0 );
+				    	
 				    	GridData gridData = new GridData();
 						
 						gridData.heightHint 				= 0;
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/UIMessageImpl.java b/org/gudy/azureus2/ui/swt/pluginsimpl/UIMessageImpl.java
index a4e0c7b..7a39a2f 100644
--- a/org/gudy/azureus2/ui/swt/pluginsimpl/UIMessageImpl.java
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/UIMessageImpl.java
@@ -21,32 +21,33 @@
 package org.gudy.azureus2.ui.swt.pluginsimpl;
 
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Shell;
 
 import org.gudy.azureus2.pluginsimpl.local.ui.AbstractUIMessage;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
 /**
  * @author Allan Crooks
  *
  */
-public class UIMessageImpl extends AbstractUIMessage {
-	
+public class UIMessageImpl
+	extends AbstractUIMessage
+{
+
 	public UIMessageImpl() {
 	}
 
 	public int ask() {
 		final int[] result = new int[1];
 		Utils.execSWTThread(new Runnable() {
-			public void run() {result[0] = ask0();}
+			public void run() {
+				result[0] = ask0();
+			}
 		}, false);
 		return result[0];
 	}
-	
+
 	private int ask0() {
-		final Shell shell = org.gudy.azureus2.ui.swt.components.shell.ShellFactory.createShell(Utils.findAnyShell(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
-		Utils.setShellIcon(shell);
-		
 		int style = 0;
 		switch (this.input_type) {
 			case INPUT_OK_CANCEL:
@@ -69,7 +70,7 @@ public class UIMessageImpl extends AbstractUIMessage {
 				style |= SWT.NO;
 				break;
 		}
-		
+
 		switch (this.message_type) {
 			case MSG_ERROR:
 				style |= SWT.ICON_ERROR;
@@ -87,8 +88,12 @@ public class UIMessageImpl extends AbstractUIMessage {
 				style |= SWT.ICON_WORKING;
 				break;
 		}
-		
-		int result = Utils.openMessageBox(shell, style, this.title, this.messagesAsString());
+
+		MessageBoxShell mb = new MessageBoxShell(style, this.title,
+				this.messagesAsString());
+		mb.open(null);
+		int result = mb.waitUntilClosed();
+
 		switch (result) {
 			case SWT.OK:
 				return ANSWER_OK;
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTInstanceImpl.java b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTInstanceImpl.java
index f2497c3..28430f1 100644
--- a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTInstanceImpl.java
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTInstanceImpl.java
@@ -33,13 +33,11 @@ import java.util.WeakHashMap;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.awt.SWT_AWT;
-import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.ImageData;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.*;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Event;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.download.DownloadManager;
@@ -62,6 +60,7 @@ import org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl;
 import org.gudy.azureus2.pluginsimpl.local.ui.UIManagerImpl;
 import org.gudy.azureus2.ui.common.util.MenuItemManager;
 import org.gudy.azureus2.ui.swt.*;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.*;
 import org.gudy.azureus2.ui.swt.minibar.AllTransfersBar;
 import org.gudy.azureus2.ui.swt.minibar.DownloadBar;
@@ -196,35 +195,32 @@ UISWTInstanceImpl
 							}
 							
 
-							Shell shell = uiFunctions.getMainShell();
+							MessageBoxShell mb = new MessageBoxShell(styles, 
+									MessageText.getString((String)params[0]), 
+									MessageText.getString((String)params[1]));
+							mb.open(null);
+							int _r = mb.waitUntilClosed();
+							
+							int	r = 0;
 							
-							if ( shell != null ){
+							if (( _r & SWT.YES ) != 0 ){
 								
-								int _r = Utils.openMessageBox(shell, styles, 
-										MessageText.getString((String)params[0]), 
-										MessageText.getString((String)params[1]));
+								r |= UIManagerEvent.MT_YES;
+							}
+							if (( _r & SWT.NO ) != 0 ){
 								
-								int	r = 0;
+								r |= UIManagerEvent.MT_NO;
+							}
+							if (( _r & SWT.OK ) != 0 ){
 								
-								if (( _r & SWT.YES ) != 0 ){
-									
-									r |= UIManagerEvent.MT_YES;
-								}
-								if (( _r & SWT.NO ) != 0 ){
-									
-									r |= UIManagerEvent.MT_NO;
-								}
-								if (( _r & SWT.OK ) != 0 ){
-									
-									r |= UIManagerEvent.MT_OK;
-								}
-								if (( _r & SWT.CANCEL ) != 0 ){
-									
-									r |= UIManagerEvent.MT_CANCEL;
-								}
+								r |= UIManagerEvent.MT_OK;
+							}
+							if (( _r & SWT.CANCEL ) != 0 ){
 								
-								result[0] = r;
+								r |= UIManagerEvent.MT_CANCEL;
 							}
+							
+							result[0] = r;
 						}
 					}, false );
 				
@@ -539,6 +535,12 @@ UISWTInstanceImpl
 	{
 		return new UISWTGraphicImpl(img);
 	}
+	
+	public Shell createShell(int style) {
+		Shell shell = ShellFactory.createMainShell(style);
+		Utils.setShellIcon(shell);
+		return shell;
+	}
   
 
 	/** @deprecated */
@@ -784,8 +786,12 @@ UISWTInstanceImpl
 	// @see org.gudy.azureus2.plugins.ui.UIInstance#promptUser(java.lang.String, java.lang.String, java.lang.String[], int)
 	public int promptUser(String title, String text, String[] options,
 			int defaultOption) {
-		return MessageBoxShell.open(uiFunctions.getMainShell(), title, text,
-				options, defaultOption);
+		
+		MessageBoxShell mb = new MessageBoxShell(title, text, options,
+				defaultOption);
+		mb.open(null);
+		// bah, no way to change this to use the UserPrompterResultListener trigger
+		return mb.waitUntilClosed();
 	}
 	
 	public void showDownloadBar(Download download, final boolean display) {
@@ -845,25 +851,16 @@ UISWTInstanceImpl
 		final UISWTStatusEntryImpl entry = new UISWTStatusEntryImpl();
 		UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
 		if (functionsSWT == null) {
+			Debug.outNoStack("No UIFunctionsSWT on createStatusEntry");
 			return null;
 		}
 		
 		MainStatusBar mainStatusBar = functionsSWT.getMainStatusBar();
 		if (mainStatusBar == null) {
+			Debug.outNoStack("No MainStatusBar on createStatusEntry");
 			return null;
 		}
-		final CLabel label = mainStatusBar.createStatusEntry(entry);
-		final Listener click_listener = new Listener() {
-			public void handleEvent(Event e) {
-				entry.onClick();
-			}
-		};
-
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				label.addListener(SWT.MouseDoubleClick, click_listener);
-			}
-		}, true);
+		mainStatusBar.createStatusEntry(entry);
 		
 		return entry;
 	}
@@ -1030,6 +1027,10 @@ UISWTInstanceImpl
 		public void openConfig(BasicPluginConfigModel model) {
 			delegate.openConfig(model);
 		}
+
+		public Shell createShell(int style) {
+			return delegate.createShell(style);
+		}
 		
 	}
 	
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTStatusEntryImpl.java b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTStatusEntryImpl.java
index b695fa1..248e248 100644
--- a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTStatusEntryImpl.java
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTStatusEntryImpl.java
@@ -6,15 +6,20 @@ package org.gudy.azureus2.ui.swt.pluginsimpl;
 import java.util.Iterator;
 import java.util.concurrent.CopyOnWriteArrayList;
 
+import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.events.MenuEvent;
 import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Menu;
 
 import org.gudy.azureus2.core3.util.AEMonitor;
+import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.pluginsimpl.local.ui.menus.MenuContextImpl;
 import org.gudy.azureus2.ui.common.util.MenuItemManager;
 import org.gudy.azureus2.ui.swt.MenuBuildUtils;
+import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.MainStatusBar;
 import org.gudy.azureus2.ui.swt.plugins.UISWTStatusEntry;
 import org.gudy.azureus2.ui.swt.plugins.UISWTStatusEntryListener;
@@ -229,4 +234,17 @@ public class UISWTStatusEntryImpl implements UISWTStatusEntry, MainStatusBar.CLa
 		this_mon.exit();
 	}
 
+	public void created(final CLabel label) {
+		final Listener click_listener = new Listener() {
+			public void handleEvent(Event e) {
+				onClick();
+			}
+		};
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				label.addListener(SWT.MouseDoubleClick, click_listener);
+			}
+		}, true);
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/sharing/progress/ProgressWindow.java b/org/gudy/azureus2/ui/swt/sharing/progress/ProgressWindow.java
index c902113..486c9f9 100644
--- a/org/gudy/azureus2/ui/swt/sharing/progress/ProgressWindow.java
+++ b/org/gudy/azureus2/ui/swt/sharing/progress/ProgressWindow.java
@@ -292,9 +292,10 @@ ProgressWindow
 	
 	public void
 	resourceModified(
-		ShareResource		resource )
+		ShareResource		old_resource,
+		ShareResource		new_resource )
 	{
-		reportCurrentTask( "Resource modified: " + resource.getName());
+		reportCurrentTask( "Resource modified: " + old_resource.getName());
 	}
 	
 	public void
diff --git a/org/gudy/azureus2/ui/swt/shells/AdvRenameWindow.java b/org/gudy/azureus2/ui/swt/shells/AdvRenameWindow.java
new file mode 100644
index 0000000..ed8c170
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/shells/AdvRenameWindow.java
@@ -0,0 +1,243 @@
+/*
+ * Created on Sep 3, 2009 3:12:13 PM
+ * Copyright (C) 2009 Aelitis, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * AELITIS, SAS au capital de 46,603.30 euros
+ * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
+ */
+package org.gudy.azureus2.ui.swt.shells;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.logging.LogAlert;
+import org.gudy.azureus2.core3.logging.Logger;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
+
+import com.aelitis.azureus.ui.common.RememberedDecisionsManager;
+
+/**
+ * @author TuxPaper
+ * @created Sep 3, 2009
+ *
+ */
+public class AdvRenameWindow
+{
+	private DownloadManager dm;
+
+	private Shell shell;
+
+	private String newName = null;
+
+	protected int renameDecisions;
+
+	private static final int RENAME_DISPLAY = 0x1;
+
+	private static final int RENAME_SAVEPATH = 0x2;
+
+	private static final int RENAME_TORRENT = 0x4;
+
+	public static void main(String[] args) {
+		AdvRenameWindow window = new AdvRenameWindow();
+		window.open(null);
+		window.waitUntilDone();
+	}
+
+	public AdvRenameWindow() {
+	}
+
+	public void open(DownloadManager dm) {
+		this.dm = dm;
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				openInSWT();
+			}
+		});
+	}
+
+	private void openInSWT() {
+		shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM | SWT.RESIZE);
+		Utils.setShellIcon(shell);
+		shell.addTraverseListener(new TraverseListener() {
+			public void keyTraversed(TraverseEvent e) {
+				if (e.detail == SWT.TRAVERSE_ESCAPE) {
+					shell.dispose();
+				}
+			}
+		});
+
+		Messages.setLanguageText(shell, "AdvRenameWindow.title");
+
+		Label lblMessage = new Label(shell, SWT.WRAP);
+		Messages.setLanguageText(lblMessage, "AdvRenameWindow.message");
+
+		final Text txtInput = new Text(shell, SWT.BORDER);
+		txtInput.setText(dm == null ? "" : dm.getDisplayName());
+
+		final Button btnDisplayName = new Button(shell, SWT.CHECK);
+		Messages.setLanguageText(btnDisplayName,
+				"MyTorrentsView.menu.rename.displayed");
+
+		final Button btnSavePath = new Button(shell, SWT.CHECK);
+		Messages.setLanguageText(btnSavePath,
+				"MyTorrentsView.menu.rename.save_path");
+
+		final Button btnTorrent = new Button(shell, SWT.CHECK);
+		Messages.setLanguageText(btnTorrent, "AdvRenameWindow.rename.torrent");
+
+		Composite cButtons = new Composite(shell, SWT.NONE);
+		RowLayout rowLayout = new RowLayout(SWT.HORIZONTAL);
+		rowLayout.fill = true;
+		rowLayout.spacing = 5;
+		cButtons.setLayout(rowLayout);
+
+		Button btnOk = new Button(cButtons, SWT.PUSH);
+		Messages.setLanguageText(btnOk, "Button.ok");
+		shell.setDefaultButton(btnOk);
+		btnOk.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				newName = txtInput.getText();
+
+				renameDecisions = 0;
+				if (btnDisplayName.getSelection()) {
+					renameDecisions |= RENAME_DISPLAY;
+				}
+				if (btnSavePath.getSelection()) {
+					renameDecisions |= RENAME_SAVEPATH;
+				}
+				if (btnTorrent.getSelection()) {
+					renameDecisions |= RENAME_TORRENT;
+				}
+				RememberedDecisionsManager.setRemembered("adv.rename", renameDecisions);
+
+				Utils.getOffOfSWTThread(new AERunnable() {
+					public void runSupport() {
+						doRename();
+					}
+				});
+
+				shell.dispose();
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+
+		Button btnCancel = new Button(cButtons, SWT.PUSH);
+		Messages.setLanguageText(btnCancel, "Button.cancel");
+		btnCancel.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				shell.dispose();
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+
+		shell.setLayout(new FormLayout());
+
+		FormData fd;
+		fd = new FormData();
+		fd.top = new FormAttachment(0, 3);
+		fd.left = new FormAttachment(0, 3);
+		fd.right = new FormAttachment(100, -3);
+		lblMessage.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.top = new FormAttachment(lblMessage, 5);
+		fd.left = new FormAttachment(0, 3);
+		fd.right = new FormAttachment(100, -3);
+		fd.width = 300;
+		txtInput.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.top = new FormAttachment(txtInput, 5);
+		fd.left = new FormAttachment(0, 8);
+		fd.right = new FormAttachment(100, -3);
+		btnDisplayName.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.top = new FormAttachment(btnDisplayName, 2);
+		fd.left = new FormAttachment(0, 8);
+		fd.right = new FormAttachment(100, -3);
+		btnSavePath.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.top = new FormAttachment(btnSavePath, 2);
+		fd.left = new FormAttachment(0, 8);
+		fd.right = new FormAttachment(100, -3);
+		btnTorrent.setLayoutData(fd);
+
+		int renameDecisions = RememberedDecisionsManager.getRememberedDecision("adv.rename");
+		if ((renameDecisions & RENAME_DISPLAY) > 0) {
+			btnDisplayName.setSelection(true);
+		}
+		if ((renameDecisions & RENAME_SAVEPATH) > 0) {
+			btnSavePath.setSelection(true);
+		}
+		if ((renameDecisions & RENAME_TORRENT) > 0) {
+			btnTorrent.setSelection(true);
+		}
+
+		fd = new FormData();
+		fd.top = new FormAttachment(btnTorrent, 5);
+		fd.right = new FormAttachment(100, -3);
+		fd.bottom = new FormAttachment(100, -3);
+		cButtons.setLayoutData(fd);
+
+		shell.pack();
+		Utils.centreWindow(shell);
+		shell.open();
+	}
+	
+	private void waitUntilDone() {
+		while (shell != null && !shell.isDisposed()) {
+			if (!shell.getDisplay().readAndDispatch()) {
+				shell.getDisplay().sleep();
+			}
+		}
+	}
+
+	private void doRename() {
+		if (dm == null) {
+			return;
+		}
+		if ((renameDecisions & RENAME_DISPLAY) > 0) {
+			dm.getDownloadState().setDisplayName(newName);
+		}
+		if ((renameDecisions & RENAME_SAVEPATH) > 0) {
+			try {
+				dm.renameDownload(newName);
+			} catch (Exception e) {
+				Logger.log(new LogAlert(dm, LogAlert.REPEATABLE,
+						"Download data rename operation failed", e));
+			}
+		}
+		if ((renameDecisions & RENAME_TORRENT) > 0) {
+			try {
+				dm.renameTorrentSafe(newName);
+  		} catch (Exception e) {
+  			Logger.log(new LogAlert(dm, LogAlert.REPEATABLE,
+  					"Torrent rename operation failed", e));
+  		}
+		}
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/shells/BrowserShell.java b/org/gudy/azureus2/ui/swt/shells/BrowserShell.java
index a43d973..f58252a 100644
--- a/org/gudy/azureus2/ui/swt/shells/BrowserShell.java
+++ b/org/gudy/azureus2/ui/swt/shells/BrowserShell.java
@@ -21,9 +21,7 @@
 
 package org.gudy.azureus2.ui.swt.shells;
 
-import org.eclipse.swt.widgets.Shell;
 import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.ui.swt.Utils;
 
 public class 
 BrowserShell 
@@ -35,11 +33,8 @@ BrowserShell
 		int			width,
 		int			height )
 	{
-		Shell parent_shell = Utils.findAnyShell();
-		
 		MessageBoxShell boxShell = 
 			new MessageBoxShell(
-				parent_shell,
 				MessageText.getString( title_resource ),
 				"",
 				new String[] {
@@ -55,6 +50,6 @@ BrowserShell
 		
 		boxShell.setSize( width, height );
 		
-		boxShell.open();
+		boxShell.open(null);
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/shells/CoreWaiterSWT.java b/org/gudy/azureus2/ui/swt/shells/CoreWaiterSWT.java
index a1050f0..58731ca 100644
--- a/org/gudy/azureus2/ui/swt/shells/CoreWaiterSWT.java
+++ b/org/gudy/azureus2/ui/swt/shells/CoreWaiterSWT.java
@@ -28,20 +28,6 @@ public class CoreWaiterSWT
 
 	public static void waitForCore(final TriggerInThread triggerInThread,
 			final AzureusCoreRunningListener l) {
-		if (!AzureusCoreFactory.isCoreRunning()) {
-			if (DEBUG) {
-				System.out.println("NOT AVAIL FOR " + Debug.getCompressedStackTrace());
-			}
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					showWaitWindow();
-				}
-			});
-		} else if (DEBUG) {
-			System.out.println("NO NEED TO WAIT.. CORE AVAIL! "
-					+ Debug.getCompressedStackTrace());
-		}
-
 		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(final AzureusCore core) {
 				if (triggerInThread == TriggerInThread.ANY_THREAD) {
@@ -68,6 +54,21 @@ public class CoreWaiterSWT
 				});
 			}
 		});
+
+		if (!AzureusCoreFactory.isCoreRunning()) {
+			if (DEBUG) {
+				System.out.println("NOT AVAIL FOR " + Debug.getCompressedStackTrace());
+			}
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					showWaitWindow();
+				}
+			});
+		} else if (DEBUG) {
+			System.out.println("NO NEED TO WAIT.. CORE AVAIL! "
+					+ Debug.getCompressedStackTrace());
+		}
+
 	}
 
 	protected static void showWaitWindow() {
diff --git a/org/gudy/azureus2/ui/swt/shells/GCStringPrinter.java b/org/gudy/azureus2/ui/swt/shells/GCStringPrinter.java
index 0df06a9..ff4eecb 100644
--- a/org/gudy/azureus2/ui/swt/shells/GCStringPrinter.java
+++ b/org/gudy/azureus2/ui/swt/shells/GCStringPrinter.java
@@ -96,6 +96,10 @@ public class GCStringPrinter
 	
 	private float[] imageScales;
 
+	private int iCurrentHeight;
+
+	private boolean wrap;
+
 	public static class URLInfo
 	{
 		public String url;
@@ -213,6 +217,11 @@ public class GCStringPrinter
 		} catch (Throwable t) {
 			Debug.out(t);
 		}
+
+		if (DEBUG) {
+			System.out.println("");
+		}
+
 		return b;
 	}
 
@@ -246,7 +255,7 @@ public class GCStringPrinter
 		boolean fullLinesOnly = (printFlags & FLAG_FULLLINESONLY) > 0;
 		boolean skipClip = (printFlags & FLAG_SKIPCLIP) > 0;
 		boolean noDraw = (printFlags & FLAG_NODRAW) > 0;
-		boolean wrap = (swtFlags & SWT.WRAP) > 0;
+		wrap = (swtFlags & SWT.WRAP) > 0;
 
 		if ((printFlags & FLAG_KEEP_URL_INFO) == 0) {
 			Matcher htmlMatcher = patHREF.matcher(string);
@@ -313,7 +322,7 @@ public class GCStringPrinter
 			}
 
 			// Process string line by line
-			int iCurrentHeight = 0;
+			iCurrentHeight = 0;
 			int currentCharPos = 0;
 			
 			int pos1 = string.indexOf('\n');
@@ -331,7 +340,7 @@ public class GCStringPrinter
 
 				do {
 					LineInfo lineInfo = new LineInfo(sLine, currentCharPos);
-					lineInfo = processLine(gc, lineInfo, printArea, wrap, fullLinesOnly,
+					lineInfo = processLine(gc, lineInfo, printArea,  fullLinesOnly,
 							false);
 					String sProcessedLine = (String) lineInfo.lineOutputed;
 
@@ -359,7 +368,7 @@ public class GCStringPrinter
 						if (isOverY && !fullLinesOnly) {
 							//fullLinesOnly = true; // <-- don't know why we needed this
 							lines.add(lineInfo);
-						} else if (isOverY && fullLinesOnly) {
+						} else if (isOverY && fullLinesOnly && lines.size() > 0) {
 							String excess = lineInfo.excessPos >= 0
 									? sLine.substring(lineInfo.excessPos) : null;
 							if (excess != null) {
@@ -389,8 +398,9 @@ public class GCStringPrinter
 
 								StringBuffer outputLine = new StringBuffer(sProcessedLine);
 								lineInfo.width = extent.x;
+								wrap = false;
 								int newExcessPos = processWord(gc, sProcessedLine,
-										" " + excess, printArea, false, lineInfo, outputLine,
+										" " + excess, printArea, lineInfo, outputLine,
 										new StringBuffer());
 								if (DEBUG) {
 									System.out.println("  with word [" + excess + "] len is "
@@ -497,7 +507,6 @@ public class GCStringPrinter
 
 		}
 		
-
 		cutoff |= size.y > printArea.height;
 		return !cutoff;
 	}
@@ -509,9 +518,9 @@ public class GCStringPrinter
 	 * @since 3.0.0.7
 	 */
 	private LineInfo processLine(final GC gc, final LineInfo lineInfo,
-			final Rectangle printArea, final boolean wrap,
-			final boolean fullLinesOnly, boolean hasMoreElements) {
-		
+			final Rectangle printArea, final boolean fullLinesOnly,
+			boolean hasMoreElements) {
+
 		if (lineInfo.originalLine.length() == 0) {
 			lineInfo.lineOutputed = "";
 			lineInfo.height = gc.stringExtent(GOOD_STRING).y;
@@ -541,10 +550,13 @@ public class GCStringPrinter
 				// outputLine.append(sProcessedLine);
 
 				excessPos = processWord(gc, lineInfo.originalLine, sProcessedLine,
-						printArea, wrap, lineInfo, outputLine, space);
+						printArea, lineInfo, outputLine, space);
 			} else {
 				int posLastWordStart = 0;
 				int posWordStart = lineInfo.originalLine.indexOf(' ');
+				while (posWordStart == 0) {
+					posWordStart = lineInfo.originalLine.indexOf(' ', posWordStart + 1);
+				}
 				if (posWordStart < 0) {
 					posWordStart = lineInfo.originalLine.length();
 				}
@@ -567,7 +579,7 @@ public class GCStringPrinter
 						}
 
 						excessPos = processWord(gc, lineInfo.originalLine, subWord,
-								printArea, wrap, lineInfo, outputLine, space);
+								printArea, lineInfo, outputLine, space);
 						if (DEBUG) {
 							System.out.println("  with word [" + subWord + "] len is "
 									+ lineInfo.width + "(" + printArea.width + ") w/excess "
@@ -621,7 +633,7 @@ public class GCStringPrinter
 	 * @since 3.0.0.7
 	 */
 	private int processWord(final GC gc, final String sLine, String word,
-			final Rectangle printArea, final boolean wrap, final LineInfo lineInfo,
+			final Rectangle printArea, final LineInfo lineInfo,
 			StringBuffer outputLine, final StringBuffer space) {
 
 		if (word.length() == 0) {
@@ -686,21 +698,24 @@ public class GCStringPrinter
 			}
 		}
 
-		Point ptWordSize = gc.stringExtent(word + " ");
-		boolean bWordLargerThanWidth = ptWordSize.x > printArea.width;
-		// This will split put a word that is longer than a full line onto a new
-		// line (when the existing line has text).
-		if (bWordLargerThanWidth && lineInfo.width > 0) {
-			//System.out.println("w3 = " + lineInfo.width + ";h=" + lineInfo.height);
-			return 0;
-		}
-		int targetWidth = lineInfo.width + ptWordSize.x;
-		if (targetWidth > printArea.width) {
+		Point ptLineAndWordSize = gc.stringExtent(outputLine + word + " ");
+		//System.out.println(ptLineAndWordSize + ";" + outputLine  + "::WordComp " + (ptLineAndWordSize.x - lineInfo.width));
+		if (ptLineAndWordSize.x > printArea.width) {
 			// word is longer than space avail, split
+
+			Point ptWordSize2 = gc.stringExtent(word + " ");
+			boolean bWordLargerThanWidth = ptWordSize2.x > printArea.width;
+			// This will split put a word that is longer than a full line onto a new
+			// line (when the existing line has text).
+			if (bWordLargerThanWidth && lineInfo.width > 0) {
+				//System.out.println("w3 = " + lineInfo.width + ";h=" + lineInfo.height);
+				return 0;
+			}
+
 			int endIndex = word.length();
 			long diff = endIndex;
 
-			while (targetWidth != printArea.width) {
+			while (ptLineAndWordSize.x != printArea.width) {
 				diff = (diff >> 1) + (diff % 2);
 
 				if (diff <= 0) {
@@ -708,7 +723,7 @@ public class GCStringPrinter
 				}
 
 				//System.out.println("diff=" + diff + ";e=" + endIndex + ";tw=" + targetWidth + ";paw= " + printArea.width);
-				if (targetWidth > printArea.width) {
+				if (ptLineAndWordSize.x > printArea.width) {
 					endIndex -= diff;
 					if (endIndex < 1) {
 						endIndex = 1;
@@ -720,38 +735,42 @@ public class GCStringPrinter
 					}
 				}
 
-				ptWordSize = gc.stringExtent(word.substring(0, endIndex) + " ");
-				targetWidth = lineInfo.width + ptWordSize.x;
+				ptLineAndWordSize = gc.stringExtent(outputLine + word.substring(0, endIndex) + " ");
 
 				if (diff <= 1) {
 					break;
 				}
 			}
-			;
-			if (endIndex == 0) {
+			boolean nothingFit = endIndex == 0;
+			if (nothingFit) {
 				endIndex = 1;
 			}
-			if (targetWidth > printArea.width && endIndex > 1) {
+			if (ptLineAndWordSize.x > printArea.width && endIndex > 1) {
 				endIndex--;
-				ptWordSize = gc.stringExtent(word.substring(0, endIndex) + " ");
+				ptLineAndWordSize = gc.stringExtent(outputLine + word.substring(0, endIndex) + " ");
 			}
 
 			if (DEBUG) {
-				System.out.println("excess starts at " + endIndex + "(" + ptWordSize.x
-						+ "px) of " + word.length() + ". "
-						+ (ptWordSize.x + lineInfo.width) + "/" + printArea.width
-						+ "; wrap?" + wrap);
+				System.out.println("excess starts at " + endIndex + " of "
+						+ word.length() + ". "
+						+ "wrap?" + wrap);
 			}
-
-			if (endIndex > 0 && outputLine.length() > 0) {
-				outputLine.append(space);
+			if (wrap && (printFlags & FLAG_FULLLINESONLY) > 0) {
+				int nextLineHeight = gc.stringExtent(GOOD_STRING).y;
+				if (iCurrentHeight + ptLineAndWordSize.y + nextLineHeight > printArea.height) {
+					if (DEBUG) {
+						System.out.println("turn off wrap");
+					}
+					wrap = false;
+				}
 			}
 
-			if (endIndex == 0 && outputLine.length() == 0) {
-				endIndex = 1;
+			if (endIndex > 0 && outputLine.length() > 0 && !nothingFit) {
+				outputLine.append(space);
 			}
 
-			if (wrap && ptWordSize.x < printArea.width && !bWordLargerThanWidth) {
+			int w = ptLineAndWordSize.x - lineInfo.width;
+			if (wrap && !nothingFit && !bWordLargerThanWidth) {
 				// whole word is excess
 				return 0;
 			}
@@ -782,7 +801,7 @@ public class GCStringPrinter
 			return endIndex;
 		}
 
-		lineInfo.width += ptWordSize.x;
+		lineInfo.width = ptLineAndWordSize.x;
 		if (lineInfo.width > printArea.width) {
 			if (space.length() > 0) {
 				space.delete(0, space.length());
@@ -1104,7 +1123,8 @@ public class GCStringPrinter
 		GridData gridData = new GridData(SWT.NONE, SWT.FILL, false, true);
 		cButtons.setLayoutData(gridData);
 		final Canvas cPaint = new Canvas(shell, SWT.DOUBLE_BUFFERED);
-		gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+		gridData = new GridData(SWT.FILL, SWT.NONE, true, false);
+		gridData.heightHint = 40;
 		cPaint.setLayoutData(gridData);
 
 		cButtons.setLayout(new RowLayout(SWT.VERTICAL));
diff --git a/org/gudy/azureus2/ui/swt/shells/MessageBoxShell.java b/org/gudy/azureus2/ui/swt/shells/MessageBoxShell.java
index 566ed17..bf33d2f 100644
--- a/org/gudy/azureus2/ui/swt/shells/MessageBoxShell.java
+++ b/org/gudy/azureus2/ui/swt/shells/MessageBoxShell.java
@@ -1,5 +1,8 @@
 package org.gudy.azureus2.ui.swt.shells;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.*;
 import org.eclipse.swt.events.*;
@@ -14,6 +17,7 @@ import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
 import org.gudy.azureus2.ui.swt.shells.GCStringPrinter.URLInfo;
 
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 import com.aelitis.azureus.ui.UIFunctionsUserPrompter;
 import com.aelitis.azureus.ui.common.RememberedDecisionsManager;
 import com.aelitis.azureus.ui.swt.UISkinnableManagerSWT;
@@ -52,19 +56,21 @@ public class MessageBoxShell
 
 	private final String text;
 
-	private final String[] buttons;
+	private String[] buttons;
+
+	private Integer[] buttonVals;
 
-	private final int defaultOption;
+	private int defaultButtonPos;
 
-	private String rememberID;
+	private String rememberID = null;
 
-	private String rememberText;
+	private String rememberText = null;
 
-	private boolean rememberByDefault;
+	private boolean rememberByDefault = false;
 
-	private int rememberOnlyIfButton = -1;
+	private int rememberOnlyIfButtonPos = -1;
 
-	private int autoCloseInMS;
+	private int autoCloseInMS = 0;
 
 	private String html;
 
@@ -91,30 +97,28 @@ public class MessageBoxShell
 	protected boolean isRemembered;
 
 	private String iconImageID;
-	
-	public static int open(final Shell parent, final String title,
-			final String text, final String[] buttons, final int defaultOption) {
-		return open(parent, title, text, buttons, defaultOption, null, false, -1);
-	}
 
-	public static int open(final Shell parent, final String title,
-			final String text, final String[] buttons, final int defaultOption,
-			final String rememberID, final boolean bRememberByDefault,
-			final int autoCloseInMS) {
-		return open(parent, title, text, buttons, defaultOption, rememberID,
-				MessageText.getString("MessageBoxWindow.rememberdecision"),
-				bRememberByDefault, autoCloseInMS);
-	}
+	private UserPrompterResultListener resultListener;
+
+	private int result;
 
-	public static int open(final Shell parent, final String title,
-			final String text, final String[] buttons, final int defaultOption,
-			final String rememberID, final String rememberText,
-			final boolean bRememberByDefault, final int autoCloseInMS) {
+	private Listener filterListener;
 
-		MessageBoxShell messageBoxShell = new MessageBoxShell(parent, title, text,
-				buttons, defaultOption, rememberID, rememberText, bRememberByDefault,
-				autoCloseInMS);
-		return messageBoxShell.open();
+	private Shell shell;
+
+	private boolean opened;
+	
+	public static void open(Shell parent, String title, String text,
+			String[] buttons, int defaultOption, String rememberID,
+			String rememberText, boolean bRememberByDefault, int autoCloseInMS,
+			UserPrompterResultListener l) {
+
+		MessageBoxShell messageBoxShell = new MessageBoxShell(title, text,
+				buttons, defaultOption);
+		messageBoxShell.setRemember(rememberID, bRememberByDefault, rememberText);
+		messageBoxShell.setAutoCloseInMS(autoCloseInMS);
+		messageBoxShell.setParent(parent);
+		messageBoxShell.open(l);
 	}
 
 	public static boolean isOpen() {
@@ -122,121 +126,214 @@ public class MessageBoxShell
 	}
 
 	/**
+	 * @param shellForChildren
+	 * @param string
+	 * @param string2
+	 * @param strings
+	 */
+	public MessageBoxShell(final String title,
+			final String text, final String[] buttons, final int defaultOption) {
+		this.title = title;
+		this.text = text;
+		this.buttons = buttons;
+		this.defaultButtonPos = defaultOption;
+	}
+
+	/**
+	 * ONLY FOR OLD EMP. DO NOT USE
+	 */
+	@Deprecated
+	public MessageBoxShell(Shell parent, final String title,
+			final String text, final String[] buttons, final int defaultOption) {
+		this(title, text, buttons, defaultOption);
+		this.parent = parent;
+	}
+
+	public MessageBoxShell(String title, String text) {
+		this(title, text, null, 0);
+	}
+
+	/** Open a messagebox using resource keys for title/text
+	 * 
+	 * @param parent Parent shell for messagebox
+	 * @param style SWT styles for messagebox
+	 * @param keyPrefix message bundle key prefix used to get title and text.  
+	 *         Title will be keyPrefix + ".title", and text will be set to
+	 *         keyPrefix + ".text"
+	 * @param textParams any parameters for text
+	 */
+	public MessageBoxShell(int style, String keyPrefix,
+			String[] textParams) {
+		if ((style & (0x7f << 5)) == 0) {
+			// need at least one button
+			style |= SWT.OK;
+		}
+		final Object[] buttonInfo = swtButtonStylesToText(style);
+
+		this.title = MessageText.getString(keyPrefix + ".title");
+		this.text = MessageText.getString(keyPrefix + ".text", textParams);
+		this.buttons = (String[]) buttonInfo[0];
+		this.defaultButtonPos = 0;
+		this.rememberID = null;
+		this.rememberText = null;
+		this.rememberByDefault = false;
+		this.autoCloseInMS = -1;
+		this.buttonVals = (Integer[]) buttonInfo[1];
+		
+		setLeftImage(style & 0x1f);
+	}
+
+	/** Open a messagebox with actual title and text
+	 * 
 	 * @param parent
+	 * @param style
 	 * @param title
 	 * @param text
-	 * @param buttons
-	 * @param defaultOption
-	 * @param rememberID
-	 * @param rememberText
-	 * @param bRememberByDefault
-	 * @param autoCloseInMS
+	 * @return
 	 */
-	public MessageBoxShell(final Shell parent, final String title,
-			final String text, final String[] buttons, final int defaultOption,
-			final String rememberID, final String rememberText,
-			final boolean bRememberByDefault, final int autoCloseInMS) {
+	public MessageBoxShell(int style, String title, String text) {
+		if ((style & (0x7f << 5)) == 0) {
+			// need at least one button
+			style |= SWT.OK;
+		}
+
+		final Object[] buttonInfo = swtButtonStylesToText(style);
 
-		this.parent = parent;
 		this.title = title;
 		this.text = text;
-		this.buttons = buttons;
-		this.defaultOption = defaultOption;
-		this.rememberID = rememberID;
-		this.rememberText = rememberText;
-		this.rememberByDefault = bRememberByDefault;
-		this.autoCloseInMS = autoCloseInMS;
+		this.buttons = (String[]) buttonInfo[0];
+		this.defaultButtonPos = 0;
+		this.rememberID = null;
+		this.rememberText = null;
+		this.rememberByDefault = false;
+		this.autoCloseInMS = -1;
+		this.buttonVals = (Integer[]) buttonInfo[1];
+		
+		setLeftImage(style & 0x1f);
+	}
+
+	public void setDefaultButtonUsingStyle(int defaultStyle) {
+		Object[] defaultButtonInfo = swtButtonStylesToText(defaultStyle);
+
+		int defaultIndex = 0;
+		if (defaultButtonInfo.length > 0) {
+			String name = ((String[]) defaultButtonInfo[0])[0];
+
+			for (int i = 0; i < buttons.length; i++) {
+				if (buttons[i].equals(name)) {
+					defaultIndex = i;
+					break;
+				}
+			}
+		}
+		defaultButtonPos = defaultIndex;
 	}
 
 	/**
-	 * @param shellForChildren
-	 * @param string
-	 * @param string2
-	 * @param strings
+	 * ONLY FOR OLD EMP.  DO NOT USE.
+	 * <P>
+	 * Use {@link #open(UserPrompterResultListener)}
+	 * @return
 	 */
-	public MessageBoxShell(final Shell parent, final String title,
-			final String text, final String[] buttons, final int defaultOption) {
-		this(parent, title, text, buttons, defaultOption, null, null, false, -1);
+	@Deprecated
+	public int open() {
+		open(false);
+		return waitUntilClosed();
 	}
 
-	public int open() {
-		return open(false);
+	public void open(UserPrompterResultListener l) {
+		this.resultListener = l;
+		open(false);
+	}
+	
+	private void triggerResultListener(final int returnVal) {
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				if (resultListener == null) {
+					return;
+				}
+				int realResult = getButtonVal(returnVal);
+				resultListener.prompterClosed(realResult);
+			}
+		});
+	}
+	
+	private int getButtonVal(int buttonPos) {
+		if (buttonVals == null) {
+			return buttonPos;
+		}
+		if (buttonPos < 0 || buttonPos >= buttonVals.length) {
+			return SWT.CANCEL;
+		}
+		return buttonVals[buttonPos].intValue();
+	}
+
+	private int getButtonPos(int buttonVal) {
+		if (buttonVals == null) {
+			return buttonVal;
+		}
+		for (int i = 0; i < buttonVals.length; i++) {
+			if (buttonVals[i] == buttonVal) {
+				return i;
+			}
+		}
+		return -1;
 	}
 
-	private int open(final boolean useCustomShell) {
+	private void open(final boolean useCustomShell) {
 		if (rememberID != null) {
 			int rememberedDecision = RememberedDecisionsManager.getRememberedDecision(rememberID);
-			if (rememberedDecision >= 0) {
-				return rememberedDecision;
+			if (rememberedDecision >= 0
+					&& (rememberOnlyIfButtonPos == -1 || rememberOnlyIfButtonPos == getButtonPos(rememberedDecision))) {
+				result = getButtonPos(rememberedDecision);
+				triggerResultListener(result);
+				return;
 			}
 		}
 
-		numOpen++;
-
-		final int[] result = new int[1];
-		result[0] = -1;
-
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
-				//if (true == useCustomShell) {
-				//	result[0] = _open2();
-				//} else {
-					result[0] = _open();
-				//}
+				_open();
 			}
 		}, false);
 
-		numOpen--;
-		return result[0];
+		return;
 	}
 
-	private int _open() {
-		final int[] result = {
-			-1
-		};
+	private void _open() {
+		result = -1;
 
+		boolean ourParent = false;
 		if (parent == null || parent.isDisposed()) {
 			parent = Utils.findAnyShell();
+			ourParent = true;
 			if (parent == null || parent.isDisposed()) {
-				return result[0];
+				triggerResultListener(result);
+				return;
 			}
 		}
 
 		MouseTrackAdapter mouseAdapter = null;
-		Display display = parent.getDisplay();
+		final Display display = parent.getDisplay();
 
-		final Shell shell = ShellFactory.createShell(parent, SWT.DIALOG_TRIM
+		shell = ShellFactory.createShell(parent, SWT.DIALOG_TRIM
 				| SWT.RESIZE | SWT.APPLICATION_MODAL);
 		if (title != null) {
 			shell.setText(title);
 		}
 		shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
 
-		shell.addListener(
-			SWT.Close,
-			new Listener()
-			{
-				public void 
-				handleEvent(
-					Event arg0) 
-				{
-					try{
-						if ( shell_browser != null ){
-						
-							shell_browser.setUrl( "about:blank" );
-							shell_browser.setVisible(false);
-						}
-					}catch( Throwable e ){
-						
-					}
-				}
-			});
-		
 		shell.addListener(SWT.Dispose, new Listener() {
 			public void handleEvent(Event event) {
 				if (iconImageID != null) {
 					ImageLoader.getInstance().releaseImage(iconImageID);
 				}
+				triggerResultListener(result);
+				if (display != null && !display.isDisposed() && filterListener != null) {
+					display.removeFilter(SWT.Traverse, filterListener);
+				}
+
+				numOpen--;
 			}
 		});
 		
@@ -288,8 +385,7 @@ public class MessageBoxShell
 		if ((html != null && html.length() > 0)
 				|| (url != null && url.length() > 0)) {
 			try {
-				final Browser browser = shell_browser = new Browser(shell,
-						Utils.getInitialBrowserStyle(SWT.NONE));
+				final Browser browser = shell_browser = Utils.createSafeBrowser(shell, SWT.NONE);
 				if (url != null && url.length() > 0) {
 					browser.setUrl(url);
 				} else {
@@ -301,6 +397,9 @@ public class MessageBoxShell
 				browser.setLayoutData(gd);
 				browser.addProgressListener(new ProgressListener() {
 					public void completed(ProgressEvent event) {
+						if (shell == null || shell.isDisposed()) {
+							return;
+						}
 						browser.addLocationListener(new LocationListener() {
 							public void changing(LocationEvent event) {
 								event.doit = browser_follow_links;
@@ -389,7 +488,7 @@ public class MessageBoxShell
 
 								long endOn = ((Long) lblCloseIn.getData("CloseOn")).longValue();
 								if (SystemTime.getCurrentTime() > endOn) {
-									result[0] = defaultOption;
+									result = defaultButtonPos;
 									autoClosed = true;
 									shell.dispose();
 								} else {
@@ -460,6 +559,13 @@ public class MessageBoxShell
 			checkRemember = new Button(shell, SWT.CHECK);
 			checkRemember.setText(rememberText);
 			checkRemember.setSelection(rememberByDefault);
+			isRemembered = rememberByDefault;
+			checkRemember.addListener(SWT.Selection, new Listener() {
+				public void handleEvent(Event event) {
+					Button checkRemember = (Button) event.widget;
+					isRemembered = checkRemember.getSelection();
+				}
+			});
 
 			checkRemember.addDisposeListener(new DisposeListener() {
 				public void widgetDisposed(DisposeEvent e) {
@@ -467,8 +573,8 @@ public class MessageBoxShell
 					isRemembered = checkRemember != null && checkRemember.getSelection();
 					if (rememberID != null
 							&& isRemembered
-							&& (rememberOnlyIfButton == -1 || rememberOnlyIfButton == result[0])) {
-						RememberedDecisionsManager.setRemembered(rememberID, result[0]);
+							&& (rememberOnlyIfButtonPos == -1 || rememberOnlyIfButtonPos == result)) {
+						RememberedDecisionsManager.setRemembered(rememberID, getButtonVal(result));
 					}
 				}
 			});
@@ -493,7 +599,7 @@ public class MessageBoxShell
 			Listener buttonListener = new Listener() {
 	
 				public void handleEvent(Event event) {
-					result[0] = ((Integer) event.widget.getData()).intValue();
+					result = ((Integer) event.widget.getData()).intValue();
 					shell.dispose();
 				}
 	
@@ -520,7 +626,7 @@ public class MessageBoxShell
 					buttonWidth = size.x;
 				}
 	
-				if (i == defaultOption) {
+				if (i == defaultButtonPos) {
 					button.setFocus();
 					shell.setDefaultButton(button);
 				}
@@ -549,7 +655,7 @@ public class MessageBoxShell
 			}
 		});
 
-		Listener filterListener = new Listener() {
+		filterListener = new Listener() {
 			public void handleEvent(Event event) {
 				if (event.detail == SWT.TRAVERSE_ARROW_NEXT) {
 					event.detail = SWT.TRAVERSE_TAB_NEXT;
@@ -581,458 +687,27 @@ public class MessageBoxShell
 			shell.setSize(size);
 		}
 
-		Utils.centerWindowRelativeTo(shell, parent);
+		Shell centerRelativeToShell = parent;
+		if (ourParent) {
+			Control cursorControl = display.getCursorControl();
+			if (cursorControl != null) {
+				centerRelativeToShell = cursorControl.getShell();
+			}
+		}
+		Utils.centerWindowRelativeTo(shell, centerRelativeToShell);
 
 		for (int i = 0; i < listeners.length; i++) {
 			listeners[i].skinAfterComponents(shell, this, relatedObjects);
 		}
 
 		shell.open();
+		opened = true;
+		numOpen++;
 
-		while (!shell.isDisposed()) {
-			if (!display.readAndDispatch()) {
-				display.sleep();
-			}
-		}
-
-		if (display != null && !display.isDisposed()) {
-			display.removeFilter(SWT.Traverse, filterListener);
-		}
 
-		return result[0];
+		return;
 	}
 
-	/*
-	private int _open2() {
-		final int[] result = {
-			-1
-		};
-
-		if (parent == null || parent.isDisposed()) {
-			parent = Utils.findAnyShell();
-			if (parent == null || parent.isDisposed()) {
-				return result[0];
-			}
-		}
-
-		
-		 // Use a lighter blue color so it shows up better with the dark background
-		 
-		setUrlColor(ColorCache.getColor(parent.getDisplay(), 109, 165, 255));
-
-		MouseTrackAdapter mouseAdapter = null;
-		Display display = parent.getDisplay();
-		int styledShellBorder = 6;
-		final StyledShell sShell = new StyledShell(parent, styledShellBorder);
-		final Shell shell = sShell.getShell();
-
-		final Composite content = sShell.getContent();
-		content.setBackgroundMode(SWT.INHERIT_DEFAULT);
-
-		GridLayout gridLayout = new GridLayout();
-		gridLayout.marginHeight = 0;
-		gridLayout.marginBottom = 5;
-		gridLayout.marginWidth = 0;
-		content.setLayout(gridLayout);
-
-		Color foreground = content.getForeground();
-		//TODO : Khai : fix this properly, quick hack to make things work for now
-		if (foreground == null) {
-			foreground = ColorCache.getColor(display, 208, 208, 208);
-			content.setForeground(foreground);
-		}
-
-		Composite titleComposite = new Composite(content, SWT.NONE);
-		titleComposite.setForeground(foreground);
-		GridLayout gLayout = new GridLayout(3, false);
-		gLayout.marginHeight = 0;
-		gLayout.marginBottom = 5;
-		gLayout.marginRight = 0;
-		gLayout.marginLeft = 5;
-		titleComposite.setLayout(gLayout);
-		titleComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-		if (null != iconImage) {
-			Label lblImage = new Label(titleComposite, SWT.NONE);
-			lblImage.setImage(iconImage);
-			lblImage.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
-		}
-
-		Label titleLabel = new Label(titleComposite, SWT.WRAP);
-		titleLabel.setForeground(foreground);
-		titleLabel.setText(title);
-		titleLabel.setLayoutData(new GridData(GridData.FILL_BOTH));
-		Utils.setFontHeight(titleLabel, 12, SWT.NORMAL);
-
-		
-		 // Setting cursor and allowing moving of the shell by dragging the title
-		
-		titleLabel.setCursor(display.getSystemCursor(SWT.CURSOR_SIZEALL));
-		Listener l = new Listener() {
-			int startX, startY;
-
-			public void handleEvent(Event e) {
-				if (e.type == SWT.MouseDown && e.button == 1) {
-					startX = e.x;
-					startY = e.y;
-				}
-				if (e.type == SWT.MouseMove && (e.stateMask & SWT.BUTTON1) != 0) {
-					Point p = shell.toDisplay(e.x, e.y);
-					p.x -= startX;
-					p.y -= startY;
-					shell.setLocation(p);
-				}
-			}
-		};
-		titleLabel.addListener(SWT.MouseDown, l);
-		titleLabel.addListener(SWT.MouseMove, l);
-
-		MiniCloseButton miniCloseButton = new MiniCloseButton(titleComposite);
-		miniCloseButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false));
-		miniCloseButton.addListener(SWT.MouseUp, new Listener() {
-			public void handleEvent(Event event) {
-				sShell.close();
-			}
-		});
-
-		UISkinnableSWTListener[] listeners = UISkinnableManagerSWT.getInstance().getSkinnableListeners(
-				MessageBoxShell.class.toString());
-		for (int i = 0; i < listeners.length; i++) {
-			listeners[i].skinBeforeComponents(shell, this, relatedObjects);
-		}
-
-		FormData formData;
-		GridData gridData;
-
-		Composite textComposite = new Composite(content, SWT.NONE);
-		textComposite.setForeground(foreground);
-		textComposite.setLayout(new GridLayout(2, false));
-		textComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-		Label iconImageLabel = new Label(textComposite, SWT.NONE);
-		if (imgLeft != null && false == imgLeft.equals(iconImage)) {
-			iconImageLabel.setImage(imgLeft);
-		}
-		iconImageLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
-
-		Control linkControl;
-		linkControl = createLinkLabel(textComposite, text);
-
-		if ((html != null && html.length() > 0)
-				|| (url != null && url.length() > 0)) {
-			try {
-				final Browser browser = new Browser(content,
-						Utils.getInitialBrowserStyle(SWT.NONE));
-				if (url != null && url.length() > 0) {
-					browser.setUrl(url);
-				} else {
-					browser.setText(html);
-				}
-				GridData gd = new GridData(GridData.FILL_BOTH);
-				gd.heightHint = 200;
-				browser.setLayoutData(gd);
-				browser.addProgressListener(new ProgressListener() {
-					public void completed(ProgressEvent event) {
-						browser.addLocationListener(new LocationListener() {
-							public void changing(LocationEvent event) {
-								event.doit = false;
-							}
-
-							public void changed(LocationEvent event) {
-							}
-						});
-						browser.addOpenWindowListener(new OpenWindowListener() {
-							public void open(WindowEvent event) {
-								event.required = true;
-							}
-						});
-					}
-
-					public void changed(ProgressEvent event) {
-					}
-				});
-			} catch (Exception e) {
-				Debug.out(e);
-				if (html != null) {
-					Text text = new Text(content, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP);
-					text.setText(html);
-					GridData gd = new GridData(GridData.FILL_BOTH);
-					gd.heightHint = 200;
-					text.setLayoutData(gd);
-				}
-			}
-
-			gridData = new GridData(GridData.FILL_HORIZONTAL);
-			linkControl.setLayoutData(gridData);
-		} else {
-			gridData = new GridData(GridData.FILL_BOTH);
-			linkControl.setLayoutData(gridData);
-		}
-
-		Label lblPadding = new Label(content, SWT.NONE);
-		lblPadding.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-		// Closing in..
-		if (autoCloseInMS > 0) {
-			final Label lblCloseIn = new Label(content, SWT.WRAP);
-			lblCloseIn.setForeground(foreground);
-			GridData gData = new GridData(SWT.FILL, SWT.CENTER, true, false);
-			gData.horizontalIndent = 10;
-			lblCloseIn.setLayoutData(gData);
-
-			long endOn = SystemTime.getCurrentTime() + autoCloseInMS;
-			lblCloseIn.setData("CloseOn", new Long(endOn));
-			SimpleTimer.addPeriodicEvent("autoclose", 500, new TimerEventPerformer() {
-				public void perform(TimerEvent event) {
-					if (content.isDisposed()) {
-						event.cancel();
-						return;
-					}
-					Utils.execSWTThread(new AERunnable() {
-						public void runSupport() {
-							if (!content.isDisposed()) {
-								boolean bDelayPaused = lblCloseIn.getData("DelayPaused") != null;
-								if (bDelayPaused) {
-									return;
-								}
-
-								long endOn = ((Long) lblCloseIn.getData("CloseOn")).longValue();
-								if (SystemTime.getCurrentTime() > endOn) {
-									result[0] = defaultOption;
-									autoClosed = true;
-									sShell.close();
-								} else {
-									String sText = "";
-
-									if (lblCloseIn.isDisposed())
-										return;
-
-									if (!bDelayPaused) {
-										long delaySecs = (endOn - SystemTime.getCurrentTime()) / 1000;
-										sText = MessageText.getString("popup.closing.in",
-												new String[] {
-													String.valueOf(delaySecs)
-												});
-									}
-
-									lblCloseIn.setText(sText);
-								}
-							}
-						};
-					});
-				}
-			});
-
-			SimpleTimer.addPeriodicEvent("OverPopup", 100, new TimerEventPerformer() {
-				boolean wasOver = true;
-
-				long lEnterOn = 0;
-
-				public void perform(final TimerEvent event) {
-					if (content.isDisposed()) {
-						event.cancel();
-						return;
-					}
-					Utils.execSWTThread(new AERunnable() {
-						public void runSupport() {
-							if (content.isDisposed()) {
-								event.cancel();
-								return;
-							}
-							boolean isOver = sShell.getBounds().contains(
-									content.getDisplay().getCursorLocation());
-							if (isOver != wasOver) {
-								wasOver = isOver;
-								if (isOver) {
-									lblCloseIn.setData("DelayPaused", "");
-									lEnterOn = SystemTime.getCurrentTime();
-									lblCloseIn.setText("");
-								} else {
-									lblCloseIn.setData("DelayPaused", null);
-									if (lEnterOn > 0) {
-										long diff = SystemTime.getCurrentTime() - lEnterOn;
-										long endOn = ((Long) lblCloseIn.getData("CloseOn")).longValue()
-												+ diff;
-										lblCloseIn.setData("CloseOn", new Long(endOn));
-									}
-								}
-							}
-						}
-					});
-				}
-			});
-		}
-
-		// Remember Me
-		Composite checkRememberPanel = null;
-		if (rememberID != null) {
-			checkRememberPanel = new Composite(content, SWT.NONE);
-			GridData gData = new GridData(SWT.LEFT, SWT.CENTER, true, false);
-			gData.horizontalIndent = 10;
-			checkRememberPanel.setLayoutData(gData);
-			FormLayout checklayout = new FormLayout();
-			checkRememberPanel.setLayout(checklayout);
-			final Button checkRemember = new Button(checkRememberPanel, SWT.CHECK);
-			checkRemember.setSelection(rememberByDefault);
-
-			Label checkRememberLabel = new Label(checkRememberPanel, SWT.NONE);
-
-			checkRememberLabel.setForeground(foreground);
-			checkRememberLabel.setText(rememberText);
-
-			checkRememberLabel.addListener(SWT.MouseUp, new Listener() {
-				public void handleEvent(Event arg0) {
-					if (!checkRemember.isDisposed()) {
-						checkRemember.setSelection(!checkRemember.getSelection());
-					}
-				}
-			});
-			FormData data = new FormData();
-			data.left = new FormAttachment(checkRemember, 6);
-			data.top = new FormAttachment(checkRemember, 0, SWT.CENTER);
-			checkRememberLabel.setLayoutData(data);
-
-			checkRemember.addDisposeListener(new DisposeListener() {
-				public void widgetDisposed(DisposeEvent e) {
-					Button checkRemember = (Button) e.widget;
-					if (rememberID != null
-							&& checkRemember != null
-							&& checkRemember.getSelection()
-							&& (rememberOnlyIfButton == -1 || rememberOnlyIfButton == result[0])) {
-						RememberedDecisionsManager.setRemembered(rememberID, result[0]);
-					}
-				}
-			});
-		}
-
-		// Buttons
-
-		if ( buttons.length > 0 ){
-			Composite cButtons = new Composite(content, SWT.NONE);
-			FormLayout layout = new FormLayout();
-	
-			cButtons.setLayout(layout);
-			gridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
-			cButtons.setLayoutData(gridData);
-	
-			Control lastButton = null;
-	
-			Listener buttonListener = new Listener() {
-	
-				public void handleEvent(Event event) {
-					result[0] = ((Integer) event.widget.getData()).intValue();
-					sShell.close();
-				}
-	
-			};
-	
-			int buttonWidth = 0;
-			BubbleButton[] swtButtons = new BubbleButton[buttons.length];
-			for (int i = 0; i < buttons.length; i++) {
-				BubbleButton button = new BubbleButton(cButtons);
-				swtButtons[i] = button;
-				button.setData(new Integer(i));
-				button.setText(buttons[i]);
-				button.addListener(SWT.MouseUp, buttonListener);
-	
-				formData = new FormData();
-				if (lastButton != null) {
-					formData.left = new FormAttachment(lastButton, 20);
-				}
-	
-				button.setLayoutData(formData);
-	
-				Point size = button.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-				if (size.x > buttonWidth) {
-					buttonWidth = size.x;
-				}
-	
-				if (i == defaultOption) {
-					button.setFocus();
-				
-					 // KN: TODO: Must implement default button behavior
-					
-					//				shell.setDefaultButton(button);
-				}
-	
-				lastButton = button;
-			}
-	
-			if (buttonWidth > 0) {
-				if (buttonWidth < MIN_BUTTON_SIZE) {
-					buttonWidth = MIN_BUTTON_SIZE;
-				}
-				for (int i = 0; i < buttons.length; i++) {
-					Point size = swtButtons[i].computeSize(buttonWidth, SWT.DEFAULT);
-					swtButtons[i].setSize(size);
-					formData = (FormData) swtButtons[i].getLayoutData();
-					formData.width = buttonWidth;
-				}
-			}
-		}
-		
-		shell.addTraverseListener(new TraverseListener() {
-			public void keyTraversed(TraverseEvent event) {
-				if (event.detail == SWT.TRAVERSE_ESCAPE) {
-					shell.dispose();
-				}
-			}
-		});
-
-		Listener filterListener = new Listener() {
-			public void handleEvent(Event event) {
-				if (event.detail == SWT.TRAVERSE_ARROW_NEXT) {
-					event.detail = SWT.TRAVERSE_TAB_NEXT;
-					event.doit = true;
-				} else if (event.detail == SWT.TRAVERSE_ARROW_PREVIOUS) {
-					event.detail = SWT.TRAVERSE_TAB_PREVIOUS;
-					event.doit = true;
-				}
-			}
-		};
-		display.addFilter(SWT.Traverse, filterListener);
-
-		if (mouseAdapter != null) {
-			addMouseTrackListener(shell, mouseAdapter);
-		}
-
-		shell.pack();
-		Point size = shell.getSize();
-		if (size.x < min_size_x) {
-			size.x = min_size_x;
-			shell.setSize(size);
-		} else if (size.x > max_size_x + (2 * styledShellBorder)) {
-			size = shell.computeSize(max_size_x + (2 * styledShellBorder),
-					SWT.DEFAULT);
-			shell.setSize(size);
-		}
-
-		if (size.y < min_size_y) {
-			size.y = min_size_y;
-			shell.setSize(size);
-		}
-
-		Utils.centerWindowRelativeTo(shell, parent);
-
-		for (int i = 0; i < listeners.length; i++) {
-			listeners[i].skinAfterComponents(content, this, relatedObjects);
-		}
-
-		sShell.open();
-
-		while (!content.isDisposed()) {
-			if (!display.readAndDispatch()) {
-				display.sleep();
-			}
-		}
-
-		if (display != null && !display.isDisposed()) {
-			display.removeFilter(SWT.Traverse, filterListener);
-		}
-
-		return result[0];
-	}
-	*/
-	
 	/**
 	 * Adds mousetracklistener to composite and all it's children
 	 * 
@@ -1163,11 +838,19 @@ public class MessageBoxShell
 	}
 
 	/**
-	 * @param rememberID the rememberID to set
+	 * 
+	 * @param rememberID
+	 * @param rememberByDefault
+	 * @param rememberText null if you want the default
 	 */
-	public void setRememberID(String rememberID, boolean rememberByDefault) {
+	public void setRemember(String rememberID, boolean rememberByDefault,
+			String rememberText) {
 		this.rememberID = rememberID;
 		this.rememberByDefault = rememberByDefault;
+		this.rememberText = rememberText;
+		if (this.rememberText == null) {
+			this.rememberText = MessageText.getString("MessageBoxWindow.rememberdecision");
+		}
 	}
 
 	/**
@@ -1276,7 +959,6 @@ public class MessageBoxShell
 		shell.open();
 
 		MessageBoxShell messageBoxShell = new MessageBoxShell(
-				shell,
 				"Title",
 				"Test\n"
 						+ "THis is a very long line that tests whether the box gets really wide which is something we don't want.\n"
@@ -1285,19 +967,31 @@ public class MessageBoxShell
 					"Okay",
 					"Cancyyyyyy",
 					"Maybe"
-				}, 1, "test2",
-				MessageText.getString("MessageBoxWindow.nomoreprompting"), false, 15000);
-
+				}, 1);
+		messageBoxShell.setRemember("test2", false,
+				MessageText.getString("MessageBoxWindow.nomoreprompting"));
+		messageBoxShell.setAutoCloseInMS(15000);
+		messageBoxShell.setParent(shell);
 		messageBoxShell.setHtml("<b>Moo</b> goes the cow<p><hr>");
-		System.out.println(messageBoxShell.open());
+		messageBoxShell.open(new UserPrompterResultListener() {
+			
+			public void prompterClosed(int returnVal) {
+				System.out.println(returnVal);
+			}
+		});
+		while (!shell.isDisposed()) {
+			if (!display.isDisposed() && !display.readAndDispatch()) {
+				display.sleep();
+			}
+		}
 	}
 
 	public int getRememberOnlyIfButton() {
-		return rememberOnlyIfButton;
+		return rememberOnlyIfButtonPos;
 	}
 
 	public void setRememberOnlyIfButton(int rememberOnlyIfButton) {
-		this.rememberOnlyIfButton = rememberOnlyIfButton;
+		this.rememberOnlyIfButtonPos = rememberOnlyIfButton;
 	}
 
 	public Color getUrlColor() {
@@ -1327,4 +1021,104 @@ public class MessageBoxShell
 	public boolean isRemembered() {
 		return isRemembered;
 	}
+	
+	/** 
+	 * NOT RECOMMENDED!
+	 * <P>
+	 * TODO: Occasionaly inspect list of callers and make them use 
+	 *       {@link UserPrompterResultListener} if possible
+	 */
+	public int waitUntilClosed() {
+		Utils.execSWTThreadWithBool("waitUntilClose", new AERunnableBoolean() {
+			public boolean runSupport() {
+				if (shell == null) {
+					return false;
+				}
+				if (!opened) {
+					shell.open();
+				}
+				while (shell != null && !shell.isDisposed()) {
+					if (shell.getDisplay() != null && !shell.getDisplay().readAndDispatch()) {
+						shell.getDisplay().sleep();
+					}
+				}
+				return true;
+			}
+		});
+		int realResult = getButtonVal(result);
+
+		return realResult;
+	}
+
+	public int getResult() {
+		return result;
+	}
+
+	private static Object[] swtButtonStylesToText(int style) {
+		List buttons = new ArrayList(2);
+		List buttonVal = new ArrayList(2);
+		int buttonCount = 0;
+		if ((style & SWT.OK) > 0) {
+			buttons.add(MessageText.getString("Button.ok"));
+			buttonVal.add(new Integer(SWT.OK));
+			buttonCount++;
+		}
+		if ((style & SWT.YES) > 0) {
+			buttons.add(MessageText.getString("Button.yes"));
+			buttonVal.add(new Integer(SWT.YES));
+			buttonCount++;
+		}
+		if ((style & SWT.NO) > 0) {
+			buttons.add(MessageText.getString("Button.no"));
+			buttonVal.add(new Integer(SWT.NO));
+			buttonCount++;
+		}
+		if ((style & SWT.CANCEL) > 0) {
+			buttons.add(MessageText.getString("Button.cancel"));
+			buttonVal.add(new Integer(SWT.CANCEL));
+			buttonCount++;
+		}
+		if ((style & SWT.ABORT) > 0) {
+			buttons.add(MessageText.getString("Button.abort"));
+			buttonVal.add(new Integer(SWT.ABORT));
+			buttonCount++;
+		}
+		if ((style & SWT.RETRY) > 0) {
+			buttons.add(MessageText.getString("Button.retry"));
+			buttonVal.add(new Integer(SWT.RETRY));
+			buttonCount++;
+		}
+		if ((style & SWT.IGNORE) > 0) {
+			buttons.add(MessageText.getString("Button.ignore"));
+			buttonVal.add(new Integer(SWT.IGNORE));
+			buttonCount++;
+		}
+		return new Object[] {
+			(String[]) buttons.toArray(new String[buttonCount]),
+			(Integer[]) buttonVal.toArray(new Integer[buttonCount])
+		};
+	}
+
+	public String[] getButtons() {
+		return buttons;
+	}
+
+	public void setButtons(String[] buttons) {
+		this.buttons = buttons;
+	}
+
+	public void setButtons(int defaltButtonPos, String[] buttons, Integer[] buttonVals) {
+		this.defaultButtonPos = defaltButtonPos;
+		this.buttons = buttons;
+		this.buttonVals = buttonVals;
+	}
+
+	public Shell getParent() {
+		return parent;
+	}
+
+	public void setParent(Shell parent) {
+		this.parent = parent;
+	}
+
 }
diff --git a/org/gudy/azureus2/ui/swt/shells/MessageSlideShell.java b/org/gudy/azureus2/ui/swt/shells/MessageSlideShell.java
index a806047..668f717 100644
--- a/org/gudy/azureus2/ui/swt/shells/MessageSlideShell.java
+++ b/org/gudy/azureus2/ui/swt/shells/MessageSlideShell.java
@@ -34,7 +34,6 @@ import org.gudy.azureus2.core3.logging.LogEvent;
 import org.gudy.azureus2.core3.logging.LogIDs;
 import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.ui.swt.ImageRepository;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
@@ -64,8 +63,6 @@ import com.aelitis.azureus.ui.swt.utils.ColorCache;
  */
 public class MessageSlideShell
 {
-	private static boolean USE_SWT32_BG_SET = true;
-
 	private static final boolean DEBUG = false;
 
 	/** Slide until there's this much gap between shell and edge of screen */
@@ -335,31 +332,24 @@ public class MessageSlideShell
 		if (shell == null) {
 			shell = new Shell(display, style);
 		}
-		if (USE_SWT32_BG_SET) {
-			try {
-				shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
-			} catch (NoSuchMethodError e) {
-				// Ignore
-			} catch (NoSuchFieldError e2) {
-				// ignore
-			}
+		try {
+			shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
+		} catch (NoSuchMethodError e) {
+			// Ignore
+		} catch (NoSuchFieldError e2) {
+			// ignore
 		}
 		Utils.setShellIcon(shell);
 		shell.setText(popupParams.title);
 
 		// Disable BG Image on OSX
 		if (imgPopup == null) {
-			if (Constants.isOSX && (SWT.getVersion() < 3221 || !USE_SWT32_BG_SET)) {
-				USE_SWT32_BG_SET = false;
-				imgPopup = null;
-			} else {
-				imgPopup = ImageLoader.getInstance().getImage("popup");
-				shell.addDisposeListener(new DisposeListener() {
-					public void widgetDisposed(DisposeEvent e) {
-						ImageLoader.getInstance().releaseImage("popup");
-					}
-				});
-			}
+			imgPopup = ImageLoader.getInstance().getImage("popup");
+			shell.addDisposeListener(new DisposeListener() {
+				public void widgetDisposed(DisposeEvent e) {
+					ImageLoader.getInstance().releaseImage("popup");
+				}
+			});
 		}
 		Rectangle imgPopupBounds;
 		if (imgPopup != null) {
@@ -582,12 +572,10 @@ public class MessageSlideShell
 			gc.dispose();
 
 			boolean bAlternateDrawing = true;
-			if (USE_SWT32_BG_SET) {
-				try {
-					shell.setBackgroundImage(imgBackground);
-					bAlternateDrawing = false;
-				} catch (NoSuchMethodError e) {
-				}
+			try {
+				shell.setBackgroundImage(imgBackground);
+				bAlternateDrawing = false;
+			} catch (NoSuchMethodError e) {
 			}
 
 			if (bAlternateDrawing) {
diff --git a/org/gudy/azureus2/ui/swt/shells/MultipageWizard.java b/org/gudy/azureus2/ui/swt/shells/MultipageWizard.java
index 1adc402..e9c360b 100644
--- a/org/gudy/azureus2/ui/swt/shells/MultipageWizard.java
+++ b/org/gudy/azureus2/ui/swt/shells/MultipageWizard.java
@@ -25,12 +25,8 @@ abstract public class MultipageWizard
 
 	private Shell shell;
 
-	private Display display;
-
 	private int shellStyle;
 
-	private Shell parent;
-
 	private Composite topPanel;
 
 	private Composite contentPanel;
@@ -52,27 +48,11 @@ abstract public class MultipageWizard
 
 	private List initializedPages = new ArrayList();
 
-	public MultipageWizard(Display display, int shellStyle) {
-		this.display = display;
-		this.shellStyle = shellStyle;
-		init();
-	}
-
-	public MultipageWizard(Shell parent, int shellStyle) {
-		this.parent = parent;
-		this.shellStyle = shellStyle;
-		init();
-	}
-
 	public abstract void createPages();
 
 	private void init() {
 
-		if (null != parent) {
-			shell = ShellFactory.createShell(parent, shellStyle);
-		} else {
-			shell = ShellFactory.createShell(display, shellStyle);
-		}
+		shell = ShellFactory.createMainShell(shellStyle);
 
 		createControls();
 		createPages();
diff --git a/org/gudy/azureus2/ui/swt/shells/SimpleBrowserWindow.java b/org/gudy/azureus2/ui/swt/shells/SimpleBrowserWindow.java
index 3498bc0..c4e8f63 100644
--- a/org/gudy/azureus2/ui/swt/shells/SimpleBrowserWindow.java
+++ b/org/gudy/azureus2/ui/swt/shells/SimpleBrowserWindow.java
@@ -25,8 +25,6 @@ import org.eclipse.swt.browser.*;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Shell;
 
 import org.gudy.azureus2.ui.swt.Utils;
@@ -77,28 +75,8 @@ public class SimpleBrowserWindow
 
 		Utils.setShellIcon(shell);
 		
-		try {
-			browser = new Browser(shell, Utils.getInitialBrowserStyle(SWT.NONE));
-			
-			shell.addListener(
-					SWT.Close,
-					new Listener()
-					{
-						public void 
-						handleEvent(
-							Event arg0) 
-						{
-							try{
-								if ( browser != null ){
-								
-									browser.setUrl( "about:blank" );
-									browser.setVisible(false);
-								}
-							}catch( Throwable e ){
-							}
-						}
-					});
-		} catch (Throwable t) {
+		browser = Utils.createSafeBrowser(shell, SWT.NONE);
+		if (browser == null) {
 			shell.dispose();
 			return;
 		}
@@ -114,6 +92,9 @@ public class SimpleBrowserWindow
 
 		browser.addCloseWindowListener(new CloseWindowListener() {
 			public void close(WindowEvent event) {
+				if (shell == null || shell.isDisposed()) {
+					return;
+				}
 				shell.dispose();
 			}
 		});
@@ -121,6 +102,9 @@ public class SimpleBrowserWindow
 		browser.addTitleListener(new TitleListener() {
 
 			public void changed(TitleEvent event) {
+				if (shell == null || shell.isDisposed()) {
+					return;
+				}
 				shell.setText(event.title);
 			}
 
diff --git a/org/gudy/azureus2/ui/swt/snippets/OnTopProblem.java b/org/gudy/azureus2/ui/swt/snippets/OnTopProblem.java
deleted file mode 100644
index 6c31866..0000000
--- a/org/gudy/azureus2/ui/swt/snippets/OnTopProblem.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Created on Apr 9, 2004
- * Created by Alon Rohter
- * Copyright (C) 2004, 2005, 2006 Alon Rohter, All Rights Reserved.
- * Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- * 
- */
-package org.gudy.azureus2.ui.swt.snippets;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Tray;
-import org.eclipse.swt.widgets.TrayItem;
-
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.AEThread;
-
-/**
- * 
- */
-public class OnTopProblem {
-  private static int[] sizes = {100,120,140};
-  
-  Display display;
-  Shell mainShell;
-  Shell onTopShell;
-  
-  Label labelIter;
-  
-  int iter;
-  
-  
-  public OnTopProblem() {
-    display = new Display();
-    mainShell = new Shell(display,SWT.SHELL_TRIM);        
-    mainShell.setText("OnTopProblem");
-    
-    mainShell.setLayout(new FillLayout());
-    
-    Button btnClose = new Button(mainShell,SWT.PUSH);
-    btnClose.setText("Close");
-    btnClose.addListener(SWT.Selection,new Listener() {
-    	public void handleEvent(Event arg0) {
-    		mainShell.dispose();
-    	} 
-    });    
-    
-    mainShell.setSize(300,200);
-    mainShell.open();
-    
-    onTopShell = new Shell(mainShell,SWT.ON_TOP);
-    onTopShell.setSize(200,30);
-    onTopShell.open();
-    
-    onTopShell.setLayout(new FillLayout());
-    
-    labelIter = new Label(onTopShell,SWT.NULL);
-    
-    Tray tray = display.getSystemTray();
-    TrayItem trayItem = new TrayItem(tray,SWT.NULL);
-    trayItem.addListener(SWT.DefaultSelection, new Listener() {
-      public void handleEvent(Event e) {
-       mainShell.setVisible(true); 
-      }
-    });
-    
-    mainShell.addListener(SWT.Close, new Listener(){
-        public void handleEvent(Event e) {
-        	e.doit = false;
-          mainShell.setVisible(false);
-          onTopShell.setVisible(true);
-        }
-    });
-    
-    Thread t = new AEThread("OnTopProblem") {
-      public void runSupport() {
-       while(updateDisplay()) {
-        try { Thread.sleep(100); } catch(Exception ignore) {}   
-       }
-      }
-     };
-     
-     t.start();
-    
-    waitForDispose();
-    display.dispose();
-  }
-  
-
-  
-  public void waitForDispose() {
-    while(!mainShell.isDisposed()) {
-      if(!display.readAndDispatch())
-        display.sleep();
-    }
-  }
-  
-  public boolean updateDisplay() {
-    if(display != null && ! display.isDisposed() ) {
-      display.asyncExec(new AERunnable() {
-        public void runSupport() {
-          iter++;
-          labelIter.setText("" + iter);
-          onTopShell.setSize(sizes[iter % sizes.length],20);
-        }
-      });
-      return true;
-    }
-    return false;
-  }
-  
-  public static void main(String args[]) {
-    new OnTopProblem();
-  }
-}
diff --git a/org/gudy/azureus2/ui/swt/snippets/TableWith0sizedColumn.java b/org/gudy/azureus2/ui/swt/snippets/TableWith0sizedColumn.java
deleted file mode 100644
index 0e59b8c..0000000
--- a/org/gudy/azureus2/ui/swt/snippets/TableWith0sizedColumn.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Created on Apr 9, 2004
- * Created by Alon Rohter
- * Copyright (C) 2004, 2005, 2006 Alon Rohter, All Rights Reserved.
- * Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * AELITIS, SAS au capital de 46,603.30 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- * 
- */
-package org.gudy.azureus2.ui.swt.snippets;
-
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
-
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.AEThread;
-
-/**
- * 
- */
-public class TableWith0sizedColumn {
-  public static void main(String[] args) {
-    final Display display = new Display();
-    final Shell shell = new Shell(display,SWT.SHELL_TRIM);
-    shell.setLayout(new FillLayout());
-    
-    final Table table = new Table(shell,SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
-    table.setHeaderVisible(true);
-    
-    TableColumn column0sized = new TableColumn(table,SWT.NULL);
-    TableColumn column1 = new TableColumn(table,SWT.NULL);
-    TableColumn column2 = new TableColumn(table,SWT.NULL);
-    column0sized.setWidth(0);
-    column0sized.setResizable(false);
-    
-    column1.setWidth(200);
-    column1.setText("Column 1");
-    column2.setWidth(200);
-    column2.setText("Column 2");
-    
-    for(int i = 0 ; i < 5 ; i++) {
-      TableItem item = new TableItem(table,0);
-      item.setText(new String[] {null,"col 1 row " + i , "col 2 row " + i});
-    }
-    
-    Thread tUpdateValues = new AEThread("TableWith0sizedColumn") {
-      public void runSupport() {
-        final int[] t = new int[1];
-        t[0] = 0;
-        while(!display.isDisposed()) {
-          t[0]++;
-          display.asyncExec(new AERunnable(){
-            public void runSupport() {
-              if(table.isDisposed())
-                return;
-              TableItem[] items = table.getItems();
-              for(int i = 0 ; i < items.length ; i++) {
-                TableItem item = items[i];
-                item.setText(new String[] {null,"col 1 row " + i + " / " + t[0] , "col 2 row " + i + " / " + t[0]});
-              }
-            }
-          });
-          try { Thread.sleep(1000); } catch(Exception ignore) {}
-        }
-      }
-    };
-    
-    tUpdateValues.start();
-    
-    shell.setSize(300,300);
-    shell.open();
-    
-    while(!shell.isDisposed()) {
-      if(!display.readAndDispatch())
-        display.sleep();
-    }
-    
-    display.dispose();
-  }
-}
diff --git a/org/gudy/azureus2/ui/swt/update/FullUpdateWindow.java b/org/gudy/azureus2/ui/swt/update/FullUpdateWindow.java
index adea70b..457df25 100644
--- a/org/gudy/azureus2/ui/swt/update/FullUpdateWindow.java
+++ b/org/gudy/azureus2/ui/swt/update/FullUpdateWindow.java
@@ -113,15 +113,17 @@ public class FullUpdateWindow
 				}
 			});
 	
-			try {
-				browser = new Browser(shell, Utils.getInitialBrowserStyle(SWT.NONE));
-			} catch (Throwable t) {
+			browser = Utils.createSafeBrowser(shell, SWT.NONE);
+			if (browser == null) {
 				shell.dispose();
 				return;
 			}
 	
 			browser.addTitleListener(new TitleListener() {
 				public void changed(TitleEvent event) {
+					if (shell == null || shell.isDisposed()) {
+						return;
+					}
 					shell.setText(event.title);
 				}
 			});
@@ -130,6 +132,9 @@ public class FullUpdateWindow
 				String last = null;
 	
 				public void changed(StatusTextEvent event) {
+					if (shell == null || shell.isDisposed()) {
+						return;
+					}
 					String text = event.text.toLowerCase();
 					if (last != null && last.equals(text)) {
 						return;
diff --git a/org/gudy/azureus2/ui/swt/update/UpdateMonitor.java b/org/gudy/azureus2/ui/swt/update/UpdateMonitor.java
index 604403b..44f1645 100644
--- a/org/gudy/azureus2/ui/swt/update/UpdateMonitor.java
+++ b/org/gudy/azureus2/ui/swt/update/UpdateMonitor.java
@@ -43,9 +43,7 @@ import org.gudy.azureus2.ui.swt.progress.ProgressReportingManager;
 import org.gudy.azureus2.update.CoreUpdateChecker;
 
 import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.ui.UIFunctions;
-import com.aelitis.azureus.ui.UIFunctionsManager;
-import com.aelitis.azureus.ui.UIFunctionsUserPrompter;
+import com.aelitis.azureus.ui.*;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 
 import org.gudy.azureus2.plugins.PluginInterface;
@@ -124,12 +122,15 @@ public class UpdateMonitor
 							+ "accept.unverified.text", new String[] {
 						update.getName()
 					});
-					return uiFunctions.promptUser(title, text, new String[] {
+					UIFunctionsUserPrompter prompter = uiFunctions.getUserPrompter(title, text, new String[] {
 						MessageText.getString("Button.yes"),
 						MessageText.getString("Button.no")
-					}, 1, MSG_PREFIX + "accept.unverified",
-							MessageText.getString("MessageBoxWindow.nomoreprompting"), false,
-							0) == 0;
+					}, 1);
+					prompter.setRemember(MSG_PREFIX + "accept.unverified", false,
+							MessageText.getString("MessageBoxWindow.nomoreprompting"));
+					prompter.setAutoCloseInMS(0);
+					prompter.open(null);
+					return prompter.waitUntilClosed() == 0;
 				}
 
 				return false;
@@ -148,7 +149,7 @@ public class UpdateMonitor
 					});
 					uiFunctions.promptUser(title, text, new String[] {
 						MessageText.getString("Button.ok")
-					}, 0, null, null, false, 0);
+					}, 0, null, null, false, 0, null);
 				}
 			}
 		});
@@ -207,11 +208,10 @@ public class UpdateMonitor
 					
 												prompt.setIconResource( "warning" );
 					
-												prompt.setRememberID( "UpdateMonitor.can.not.write.to.app.dir.2", false );
+												prompt.setRemember( "UpdateMonitor.can.not.write.to.app.dir.2", false, 
+														MessageText.getString( "MessageBoxWindow.nomoreprompting" ));
 					
-												prompt.setRememberText( MessageText.getString( "MessageBoxWindow.nomoreprompting" ));
-					
-												prompt.open();
+												prompt.open(null);
 											}
 										},
 										true );
@@ -639,24 +639,27 @@ public class UpdateMonitor
 	
 	protected void
 	handleRestart()
-	{
-		UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+ {
+		final UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
 		if (uiFunctions != null) {
-			String title = MessageText.getString(MSG_PREFIX
-					+ "restart.title");
-			String text = MessageText.getString(MSG_PREFIX
-					+ "restart.text");
+			String title = MessageText.getString(MSG_PREFIX + "restart.title");
+			String text = MessageText.getString(MSG_PREFIX + "restart.text");
 			uiFunctions.bringToFront();
 			int timeout = 180000;
 			if (azCore != null && !azCore.getPluginManager().isSilentRestartEnabled()) {
 				timeout = -1;
 			}
-			if (uiFunctions.promptUser(title, text, new String[] {
+			uiFunctions.promptUser(title, text, new String[] {
 				MessageText.getString("UpdateWindow.restart"),
 				MessageText.getString("UpdateWindow.restartLater")
-			}, 0, null, null, false, timeout) == 0) {
-				uiFunctions.dispose(true, false);
-			}
+			}, 0, null, null, false, timeout, new UserPrompterResultListener() {
+
+				public void prompterClosed(int result) {
+					if (result == 0) {
+						uiFunctions.dispose(true, false);
+					}
+				}
+			});
 		}
 	}
 		
diff --git a/org/gudy/azureus2/ui/swt/update/UpdateWindow.java b/org/gudy/azureus2/ui/swt/update/UpdateWindow.java
index bb7b2c7..4fd7709 100644
--- a/org/gudy/azureus2/ui/swt/update/UpdateWindow.java
+++ b/org/gudy/azureus2/ui/swt/update/UpdateWindow.java
@@ -29,6 +29,8 @@ import java.util.List;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.Browser;
 import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
@@ -244,13 +246,15 @@ UpdateWindow
     link_area.getComponent().setLayoutData(fd);
     
     try {
-    	browser = new Browser(cInfoArea, Utils.getInitialBrowserStyle(SWT.BORDER));
-      fd = new FormData();
-      fd.top = new FormAttachment(0, 0);
-      fd.bottom = new FormAttachment(100, 0);
-      fd.right = new FormAttachment(100, 0);
-      fd.left = new FormAttachment(0, 0);
-      browser.setLayoutData(fd);
+    	browser = Utils.createSafeBrowser(cInfoArea, SWT.BORDER);
+    	if (browser != null) {
+        fd = new FormData();
+        fd.top = new FormAttachment(0, 0);
+        fd.bottom = new FormAttachment(100, 0);
+        fd.right = new FormAttachment(100, 0);
+        fd.left = new FormAttachment(0, 0);
+        browser.setLayoutData(fd);
+    	}
     } catch (Throwable t) {
     }
 
diff --git a/org/gudy/azureus2/ui/swt/updater2/SWTVersionGetter.java b/org/gudy/azureus2/ui/swt/updater2/SWTVersionGetter.java
index 2ef7c54..df75cf4 100644
--- a/org/gudy/azureus2/ui/swt/updater2/SWTVersionGetter.java
+++ b/org/gudy/azureus2/ui/swt/updater2/SWTVersionGetter.java
@@ -26,6 +26,7 @@ import java.util.Map;
 
 import org.eclipse.swt.SWT;
 
+import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.core3.util.AEVerifier;
 import org.gudy.azureus2.core3.util.Constants;
@@ -62,34 +63,6 @@ public class SWTVersionGetter {
     this.currentVersion = SWT.getVersion();
     
 
-    /**
-     * Hack to make users re-download swt package which is hacked to include
-     * our osx platform jnilib. 
-     */
-    if (currentVersion == 3232 && Constants.isOSX) {
-			PlatformManager p_man = PlatformManagerFactory.getPlatformManager();
-			if (p_man != null
-					&& !p_man.hasCapability(PlatformManagerCapabilities.GetVersion)) {
-				currentVersion = 3231;
-			}
-		}
-    
-    /* hack no longer needed as most (all?) CVS users will have rolled back by now and
-     * we're shipping with 3.1.1
-     
-    if ( currentVersion == 3206 ){
-    	
-    		// problem here with 3.2M2 that we rolled out to CVS users - it doesn't work
-    		// on windows 98 (hangs the app). We therefore decided to fall back to 3.1.1
-    		// which does work. However, to rollback the CVS users we need to make it appear
-    		// that 3206 is < 3.1.1. We do this by hacking the version here
-    	
-    	System.out.println( "Rolling back SWT version 3.2M2 to 3.1.1" );
-    	
-    	currentVersion = 3138;	// 3.1.1 is 3139
-    }
-    */
-    
     this.latestVersion = 0;
     checker	= _checker;
   }
@@ -118,19 +91,70 @@ public class SWTVersionGetter {
 					+ "and url from version check client."));
     
     Map reply = VersionCheckClient.getSingleton().getVersionCheckInfo(VersionCheckClient.REASON_CHECK_SWT);
-    
+
     String msg = "SWT version check received:";
+
+    boolean	done = false;
+    
+    if ( Constants.isOSX_10_5_OrHigher ){
     
-    byte[] version_bytes = (byte[])reply.get( "swt_version" );
-    if( version_bytes != null ) {
-      latestVersion = Integer.parseInt( new String( version_bytes ) );
-      msg += " version=" + latestVersion;
+    	String target_lib = COConfigurationManager.getStringParameter( "ConfigView.section.style.swt.library.selection" );
+    	
+    	String current_lib = SWT.getPlatform();
+    	
+    	if ( target_lib.equalsIgnoreCase( current_lib )){
+    		
+    	    byte[] version_bytes = (byte[])reply.get( "swt_version_" + target_lib );
+    	    
+    	    if ( version_bytes != null ){
+    	    	
+    	    	latestVersion = Integer.parseInt( new String( version_bytes ) );
+    	    	
+    	    	msg += " version=" + latestVersion;
+    	    	
+        		byte[] url_bytes = (byte[])reply.get( "swt_url_" + target_lib );
+
+        		if ( url_bytes != null ){
+
+           			mirrors = new String[] { new String( url_bytes ) };
+        			
+        			msg += " url=" + mirrors[0];
+        		}
+        		
+        		done = true;
+    	    }
+    	}else{
+    		
+    		byte[] url_bytes = (byte[])reply.get( "swt_url_" + target_lib );
+
+    		if ( url_bytes != null ){
+    			
+    			msg += " (platform switch from " + current_lib + " to " + target_lib + ")";
+    			
+    			mirrors = new String[] { new String( url_bytes ) };
+    			
+    			msg += " url=" + mirrors[0];
+    			
+    			latestVersion = Integer.MAX_VALUE;
+    			
+    			done = true;
+    		}
+    	}
     }
     
-    byte[] url_bytes = (byte[])reply.get( "swt_url" );
-    if( url_bytes != null ) {
-      mirrors = new String[] { new String( url_bytes ) };
-      msg += " url=" + mirrors[0];
+    if ( !done ){
+    	
+	    byte[] version_bytes = (byte[])reply.get( "swt_version" );
+	    if( version_bytes != null ) {
+	      latestVersion = Integer.parseInt( new String( version_bytes ) );
+	      msg += " version=" + latestVersion;
+	    }
+	    
+	    byte[] url_bytes = (byte[])reply.get( "swt_url" );
+	    if( url_bytes != null ) {
+	      mirrors = new String[] { new String( url_bytes ) };
+	      msg += " url=" + mirrors[0];
+	    }
     }
     
     byte[] info_bytes = (byte[])reply.get( "swt_info_url" );
diff --git a/org/gudy/azureus2/ui/swt/views/FilesView.java b/org/gudy/azureus2/ui/swt/views/FilesView.java
index 1d0cb83..00cc9a2 100644
--- a/org/gudy/azureus2/ui/swt/views/FilesView.java
+++ b/org/gudy/azureus2/ui/swt/views/FilesView.java
@@ -48,6 +48,7 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.FileUtil;
 import org.gudy.azureus2.plugins.ui.tables.TableManager;
 import org.gudy.azureus2.ui.swt.*;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.views.file.FileInfoView;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWTMenuFillListener;
@@ -66,7 +67,7 @@ import com.aelitis.azureus.ui.common.table.*;
  *         2004/Apr/23: extends TableView instead of IAbstractView
  */
 public class FilesView
-	extends TableViewTab
+	extends TableViewTab<DiskManagerFileInfo>
 	implements TableDataSourceChangedListener, TableSelectionListener,
 	TableViewSWTMenuFillListener, TableRefreshListener, DownloadManagerStateAttributeListener,
 	TableLifeCycleListener
@@ -117,11 +118,14 @@ public class FilesView
    * Initialize 
    */
 	public FilesView() {
+		super("FilesView");
+	}
+
+	public TableViewSWT<DiskManagerFileInfo> initYourTableView() {
 		tv = new TableViewSWTImpl<DiskManagerFileInfo>(
 				org.gudy.azureus2.plugins.disk.DiskManagerFileInfo.class,
-				TableManager.TABLE_TORRENT_FILES, "FilesView", basicItems,
+				TableManager.TABLE_TORRENT_FILES, getPropertiesPrefix(), basicItems,
 				"firstpiece", SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL);
-		setTableView(tv);
 		tv.setRowDefaultIconSize(new Point(16, 16));
 		tv.setEnableTabViews(true);
 		tv.setCoreTabViews(new IView[] { new FileInfoView()
@@ -132,6 +136,8 @@ public class FilesView
 		tv.addSelectionListener(this, false);
 		tv.addMenuFillListener(this);
 		tv.addLifeCycleListener(this);
+
+		return tv;
 	}
 
   
@@ -330,9 +336,10 @@ public class FilesView
     
     Listener rename_listener = new Listener() {
     	public void handleEvent(Event event) {
-    		boolean rename_it = ((Boolean)event.widget.getData("rename")).booleanValue();
-    		boolean retarget_it = ((Boolean)event.widget.getData("retarget")).booleanValue();
-    		rename(tv.getSelectedRows(), rename_it, retarget_it);
+    		final boolean rename_it = ((Boolean)event.widget.getData("rename")).booleanValue();
+    		final boolean retarget_it = ((Boolean)event.widget.getData("retarget")).booleanValue();
+				final TableRowCore[] selectedRows = tv.getSelectedRows();
+				rename(selectedRows, rename_it, retarget_it);
     	}
     };
     
@@ -342,8 +349,13 @@ public class FilesView
     
     Listener priorityListener = new Listener() {
 			public void handleEvent(Event event) {
-				changePriority(((Integer) event.widget.getData("Priority")).intValue(),
-						tv.getSelectedRows());
+				final int priority = ((Integer) event.widget.getData("Priority")).intValue();
+				final TableRowCore[] selectedRows = tv.getSelectedRows();
+				Utils.getOffOfSWTThread(new AERunnable(){
+					public void runSupport() {
+						changePriority(priority, selectedRows);
+					}
+				});
 			}
     };
 
@@ -381,14 +393,18 @@ public class FilesView
 	}
 	
 	private boolean askCanOverwrite(File file) {
-		return MessageBoxWindow.open( 
-				"FilesView.messagebox.rename.id",
-				SWT.OK | SWT.CANCEL,
-				SWT.OK, true,
-				Display.getDefault(), 
-				MessageBoxWindow.ICON_WARNING,
-				MessageText.getString( "FilesView.rename.confirm.delete.title" ),
-				MessageText.getString( "FilesView.rename.confirm.delete.text", new String[]{ file.toString()})) == SWT.OK;
+		MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.CANCEL,
+				MessageText.getString("FilesView.rename.confirm.delete.title"),
+				MessageText.getString("FilesView.rename.confirm.delete.text",
+						new String[] {
+							file.toString()
+						}));
+		mb.setDefaultButtonUsingStyle(SWT.OK);
+		mb.setRememberOnlyIfButton(0);
+		mb.setRemember("FilesView.messagebox.rename.id", true, null);
+		mb.setLeftImage(SWT.ICON_WARNING);
+		mb.open(null);
+		return mb.waitUntilClosed() == SWT.OK;
 	}
 	
 	// same code is used in tableitems.files.NameItem
@@ -408,10 +424,9 @@ public class FilesView
 		is_changing_links = false;
 
 		if (!result[0]){
-			MessageBox mb = new MessageBox(Utils.findAnyShell(), SWT.ICON_ERROR | SWT.OK);
-			mb.setText(MessageText.getString("FilesView.rename.failed.title"));
-			mb.setMessage(MessageText.getString("FilesView.rename.failed.text"));
-			mb.open();	    					
+			new MessageBoxShell(SWT.ICON_ERROR | SWT.OK, 
+					MessageText.getString("FilesView.rename.failed.title"),
+					MessageText.getString("FilesView.rename.failed.text")).open(null);
 		}
 
 	}
@@ -429,8 +444,8 @@ public class FilesView
 		boolean	paused = false;
 		try {
 			for (int i=0; i<rows.length; i++) {
-				TableRowCore row = rows[i];
-				DiskManagerFileInfo fileInfo = (DiskManagerFileInfo)rows[i].getDataSource(true);
+				final TableRowCore row = rows[i];
+				final DiskManagerFileInfo fileInfo = (DiskManagerFileInfo)rows[i].getDataSource(true);
 				File existing_file = fileInfo.getFile(true);
 				File f_target = null;
 				if (rename_it && retarget_it) {
@@ -468,8 +483,13 @@ public class FilesView
     				// no existing file.
     			}
     					
-    			moveFile(fileInfo, f_target);
-    			row.invalidate();
+    			final File ff_target = f_target;
+  				Utils.getOffOfSWTThread(new AERunnable(){
+  					public void runSupport() {
+  						moveFile(fileInfo, ff_target);
+  	    			row.invalidate();
+  					}
+  				});
 			}
 		}
 		finally {
@@ -561,17 +581,22 @@ public class FilesView
 			if (root_exists) {perform_check = true;}
 			else if (FileUtil.isAncestorOf(save_location, existing_file)) {perform_check = false;}
 			else {perform_check = true;}
-						
+
 			if (perform_check && existing_file.exists()) {
-				if (delete_action) {
-					boolean wants_to_delete = MessageBoxWindow.open( 
-							"FilesView.messagebox.delete.id",
-							SWT.OK | SWT.CANCEL,
-							SWT.OK, true,
-							Display.getDefault(), 
-							MessageBoxWindow.ICON_WARNING,
-							MessageText.getString( "FilesView.rename.confirm.delete.title" ),
-							MessageText.getString( "FilesView.rename.confirm.delete.text", new String[]{ existing_file.toString()})) == SWT.OK;
+					if (delete_action) {
+						MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.CANCEL,
+								MessageText.getString("FilesView.rename.confirm.delete.title"),
+								MessageText.getString("FilesView.rename.confirm.delete.text",
+										new String[] {
+											existing_file.toString()
+										}));
+						mb.setDefaultButtonUsingStyle(SWT.OK);
+						mb.setRememberOnlyIfButton(0);
+						mb.setRemember("FilesView.messagebox.delete.id", true, null);
+						mb.setLeftImage(SWT.ICON_WARNING);
+						mb.open(null);
+
+					boolean wants_to_delete = mb.waitUntilClosed() == SWT.OK;
 					
 					if (wants_to_delete) {new_storage_type = DiskManagerFileInfo.ST_COMPACT;}
 				}
@@ -699,11 +724,7 @@ public class FilesView
     if (sColumnName.equals("path")) {
       path_item = new MenuItem( menuThisColumn, SWT.CHECK );
       
-      menuThisColumn.addListener( SWT.Show, new Listener() {
-        public void handleEvent(Event e) {
-          path_item.setSelection( show_full_path );
-        }
-      });
+      path_item.setSelection( show_full_path );
       
       Messages.setLanguageText(path_item, "FilesView.fullpath");
       
diff --git a/org/gudy/azureus2/ui/swt/views/GeneralView.java b/org/gudy/azureus2/ui/swt/views/GeneralView.java
index 8dbb2d2..1d9c83d 100644
--- a/org/gudy/azureus2/ui/swt/views/GeneralView.java
+++ b/org/gudy/azureus2/ui/swt/views/GeneralView.java
@@ -173,7 +173,11 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     genLayout.numColumns = 1;
     genComposite.setLayout(genLayout);
 
-    refreshInfo();
+    Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				refreshInfo();
+			}
+		});
     COConfigurationManager.addParameterListener("Graphics Update", this);
   }
   
@@ -696,13 +700,6 @@ public class GeneralView extends AbstractIView implements ParameterListener,
       }
     });
 
-    if( Constants.isOSX ) {
-      Shell shell = genComposite.getShell();
-      Point size = shell.getSize();
-      shell.setSize(size.x-1,size.y-1);
-      shell.setSize(size);
-    }
-    
     genComposite.addDisposeListener(new DisposeListener() {
     	public void widgetDisposed(DisposeEvent e) {
     		menuTracker.dispose();
@@ -724,7 +721,7 @@ public class GeneralView extends AbstractIView implements ParameterListener,
    * @see org.gudy.azureus2.ui.swt.IView#refresh()
    */
   public void refresh() {
-    if(getComposite() == null || getComposite().isDisposed() || manager == null)
+    if(gFile == null || gFile.isDisposed() || manager == null)
       return;
 
     loopFactor++;
diff --git a/org/gudy/azureus2/ui/swt/views/ManagerView.java b/org/gudy/azureus2/ui/swt/views/ManagerView.java
index cb0422b..b2e34cb 100644
--- a/org/gudy/azureus2/ui/swt/views/ManagerView.java
+++ b/org/gudy/azureus2/ui/swt/views/ManagerView.java
@@ -173,7 +173,7 @@ public class ManagerView
     //Don't ask me why, but without this an exception is thrown further
     // (in folder.dispose() )
     //TODO : Investigate to see if it's a platform (OSX-Carbon) BUG, and report to SWT team.
-    if(Constants.isOSX) {
+    if(Utils.isCarbon) {
       if(folder != null && !folder.isDisposed()) {
         CTabItem[] items = folder.getItems();
         for(int i=0 ; i < items.length ; i++) {
@@ -240,6 +240,7 @@ public class ManagerView
   	for (int i = 0; i < views.length; i++)
 		addSection(views[i], manager);
 
+
     // Call plugin listeners
 		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
 		if (uiFunctions != null) {
@@ -263,10 +264,11 @@ public class ManagerView
 			}
 		}
 		
-    
+
     // Initialize view when user selects it
     folder.addSelectionListener(new SelectionAdapter() {
       public void widgetSelected(SelectionEvent e) {
+      	folder.getShell().setCursor(e.display.getSystemCursor(SWT.CURSOR_WAIT));
       	// Send one last refresh to previous tab, just in case it
       	// wants to do something when view goes invisible
         refresh();
@@ -285,6 +287,7 @@ public class ManagerView
         }
         refresh();
     		ViewTitleInfoManager.refreshTitleInfo(ManagerView.this);
+      	folder.getShell().setCursor(e.display.getSystemCursor(SWT.CURSOR_ARROW));
       }
     });
     
diff --git a/org/gudy/azureus2/ui/swt/views/MySharesView.java b/org/gudy/azureus2/ui/swt/views/MySharesView.java
index ab2c39c..b8eb7b9 100644
--- a/org/gudy/azureus2/ui/swt/views/MySharesView.java
+++ b/org/gudy/azureus2/ui/swt/views/MySharesView.java
@@ -47,6 +47,7 @@ import org.gudy.azureus2.plugins.ui.tables.TableManager;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentManagerImpl;
 import org.gudy.azureus2.ui.swt.*;
+import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWTMenuFillListener;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab;
@@ -89,10 +90,10 @@ implements ShareManagerListener,
 	public 
 	MySharesView()
 	{	
+		super("MySharesView");
 		tv = new TableViewSWTImpl<ShareResource>(ShareResource.class, TableManager.TABLE_MYSHARES,
-				"MySharesView", basicItems, "name", SWT.MULTI | SWT.FULL_SELECTION
+				getPropertiesPrefix(), basicItems, "name", SWT.MULTI | SWT.FULL_SELECTION
 						| SWT.BORDER | SWT.VIRTUAL);
-		setTableView(tv);
 
 		tv.addSelectionListener(new TableSelectionAdapter() {
 			public void defaultSelected(TableRowCore[] rows, int stateMask) {
@@ -106,6 +107,10 @@ implements ShareManagerListener,
 		tv.addRefreshListener(this, false);
 		tv.addSelectionListener(this, false);
 	}
+
+	public TableViewSWT initYourTableView() {
+  	return tv;
+  }
 	
 	private void defaultSelected(TableRowCore[] rows) {
 		ShareResource share = tv.getFirstSelectedDataSource();
@@ -233,7 +238,10 @@ implements ShareManagerListener,
 	  tv.addDataSource(resource);
 	}
 	
-	public void resourceModified(ShareResource resource) { }
+	public void resourceModified(ShareResource old_resource,ShareResource new_resource) {
+		tv.removeDataSource( old_resource );
+		tv.addDataSource( new_resource );
+	}
 	
 	public void resourceDeleted(ShareResource resource) {
 	  tv.removeDataSource(resource);
diff --git a/org/gudy/azureus2/ui/swt/views/MyTorrentsView.java b/org/gudy/azureus2/ui/swt/views/MyTorrentsView.java
index 8c12aa3..9c28abc 100644
--- a/org/gudy/azureus2/ui/swt/views/MyTorrentsView.java
+++ b/org/gudy/azureus2/ui/swt/views/MyTorrentsView.java
@@ -24,7 +24,6 @@ package org.gudy.azureus2.ui.swt.views;
 
 import java.util.*;
 import java.util.List;
-import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.eclipse.swt.SWT;
@@ -55,14 +54,10 @@ import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.*;
 import org.gudy.azureus2.ui.swt.URLTransfer;
 import org.gudy.azureus2.ui.swt.help.HealthHelpWindow;
-import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
 import org.gudy.azureus2.ui.swt.minibar.DownloadBar;
 import org.gudy.azureus2.ui.swt.views.ViewUtils.SpeedAdapter;
-import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
-import org.gudy.azureus2.ui.swt.views.table.TableViewSWTMenuFillListener;
-import org.gudy.azureus2.ui.swt.views.table.TableViewSWTPanelCreator;
-import org.gudy.azureus2.ui.swt.views.table.impl.TableCellImpl;
+import org.gudy.azureus2.ui.swt.views.table.*;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
@@ -101,17 +96,10 @@ public class MyTorrentsView
                   TableSelectionListener,
                   TableViewSWTMenuFillListener,
                   TableRefreshListener,
-                  TableCountChangeListener
+                  TableCountChangeListener,
+                  TableViewFilterCheck
 {
 	private static final LogIDs LOGID = LogIDs.GUI;
-	private static final int ASYOUTYPE_MODE_FIND = 0;
-	private static final int ASYOUTYPE_MODE_FILTER = 1;
-	private static final int ASYOUTYPE_MODE = ASYOUTYPE_MODE_FILTER;
-	private static final int ASYOUTYPE_UPDATEDELAY = 300;
-	
-	/** Experimental Table UI.  When setting to true, some code needs 
-	 *  uncommenting as well */
-	private static final boolean EXPERIMENT = false;
 	
 	private AzureusCore		azureus_core;
 
@@ -135,10 +123,6 @@ public class MyTorrentsView
   private int drag_drop_line_start = -1;
   private TableRowCore[] drag_drop_rows = null;
 
-	private TimerEvent searchUpdateEvent;
-  private String sLastSearch = "";
-  private long lLastSearchTime;
-  private boolean bRegexSearch = false;
 	private boolean bDNDalwaysIncomplete;
 	private TableViewSWT tv;
 	private Composite cTableParentPanel;
@@ -149,8 +133,10 @@ public class MyTorrentsView
 	protected boolean resizeHeaderEventQueued;
 	private Button btnFilter;
 
-	public
-	MyTorrentsView() {
+	private Composite cSizer;
+
+	public MyTorrentsView() {
+		super("MyTorrentsView");
 	}
 	
   /**
@@ -167,23 +153,22 @@ public class MyTorrentsView
   		boolean 					isSeedingView,
       TableColumnCore[]	basicItems) 
   {
+		super("MyTorrentsView");
   	init(_azureus_core, tableID, isSeedingView, basicItems);
   }
   
+  // @see org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab#initYourTableView()
+  public TableViewSWT initYourTableView() {
+  	return tv;
+  }
+  
   public void init(AzureusCore _azureus_core, String tableID,
 			boolean isSeedingView, TableColumnCore[] basicItems) {
 
   	this.isSeedingView 	= isSeedingView;
   	
-  	if (EXPERIMENT) {
-//      tv = new ListView(isSeedingView ? TableManager.TABLE_MYTORRENTS_COMPLETE
-//  				: TableManager.TABLE_MYTORRENTS_INCOMPLETE, SWT.V_SCROLL);
-//      tv.setColumnList(basicItems, "#", false);
-  	} else {
-      tv = createTableView(isSeedingView ? DownloadTypeComplete.class
-  				: DownloadTypeIncomplete.class, tableID, basicItems);
-  	}
-    setTableView(tv);
+    tv = createTableView(isSeedingView ? DownloadTypeComplete.class
+				: DownloadTypeIncomplete.class, tableID, basicItems);
     tv.setRowDefaultIconSize(new Point(16, 16));
     
     /*
@@ -216,16 +201,22 @@ public class MyTorrentsView
 
   // @see com.aelitis.azureus.ui.common.table.TableLifeCycleListener#tableViewInitialized()
   public void tableViewInitialized() {
-    tv.addKeyListener(this);
+ 
+  	tv.addKeyListener(this);
 
     createTabs();
 
+    if (txtFilter == null) {
+    	tv.enableFilterCheck(null, this);
+    }
+
     createDragDrop();
 
     COConfigurationManager.addAndFireParameterListeners(new String[] {
 			"DND Always In Incomplete",
 			"Confirm Data Delete",
 			"MyTorrentsView.alwaysShowHeader",
+			"User Mode"
 		}, this);
 
     if (currentCategory != null) {
@@ -313,17 +304,6 @@ public class MyTorrentsView
     	cTableParentPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
     }
     
-    if (EXPERIMENT) {
-    	Composite cHeaders = new Composite(cTableParentPanel, SWT.NONE);
-    	gridData = new GridData(GridData.FILL_HORIZONTAL);
-    	GC gc = new GC(cHeaders);
-    	int h = gc.textExtent("alyup").y + 2;
-    	gc.dispose();
-    	gridData.heightHint = h;
-    	cHeaders.setLayoutData(gridData);
-    	//((ListView)tv).setHeaderArea(cHeaders, null, null);
-    }
-
     cTablePanel = new Composite(cTableParentPanel, SWT.NULL);
     cTablePanel.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
     cTablePanel.setForeground(composite.getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND));
@@ -353,7 +333,7 @@ public class MyTorrentsView
     GridData gridData;
     Category[] categories = CategoryManager.getCategories();
     Arrays.sort(categories);
-    boolean showCat = sLastSearch.length() > 0;
+    boolean showCat = tv.getFilterText().length() > 0;
     if (!showCat) {
 	    for(int i = 0; i < categories.length; i++) {
 	        if(categories[i].getType() == Category.TYPE_USER) {
@@ -375,156 +355,7 @@ public class MyTorrentsView
     
     if (show) {
       if (cCategories == null || cCategories.isDisposed()) {
-        Composite parent = cTableParentPanel;
-
-        cHeader = new Composite(parent, SWT.NONE);
-        gridData = new GridData(GridData.FILL_HORIZONTAL);
-        gridData.horizontalIndent = 5;
-        cHeader.setLayoutData(gridData);
-        cHeader.setLayout(new FormLayout());
-        FormData fd;
-        
-        lblHeader = new Label(cHeader, SWT.WRAP);
-        updateTableLabel();
-        
-        Label lblSep = new Label(cHeader, SWT.SEPARATOR | SWT.VERTICAL);
-        gridData = new GridData(GridData.FILL_VERTICAL);
-        gridData.heightHint = 5;
-        lblSep.setLayoutData(gridData);
-        
-        btnFilter = new Button(cHeader, SWT.TOGGLE);
-        Messages.setLanguageText(btnFilter, "MyTorrentsView.filter");
-        btnFilter.addSelectionListener(new SelectionListener() {
-				
-					public void widgetSelected(SelectionEvent e) {
-						boolean enable = btnFilter.getSelection();
-            cFilterArea.setVisible(enable);
-            if (enable) {
-            	sLastSearch = txtFilter.getText();
-            	txtFilter.setFocus();
-            } else {
-            	sLastSearch = "";
-            	tv.setFocus();
-            }
-            updateLastSearch();
-            resizeHeader();
-					}
-				
-					public void widgetDefaultSelected(SelectionEvent e) {
-					}
-				});
-        btnFilter.setSelection(sLastSearch.length() != 0);
-        
-
-        cFilterArea = new Composite(cHeader, SWT.NONE);
-        cFilterArea.setVisible(sLastSearch.length() != 0);
-        GridLayout layout = new GridLayout();
-        layout.numColumns = 5;
-        cFilterArea.setLayout(layout);
-                
-        cCategories = new Composite(cHeader, SWT.NONE);
-        RowLayout rowLayout = new RowLayout();
-        rowLayout.marginTop = 0;
-        rowLayout.marginBottom = 0;
-        rowLayout.marginLeft = 3;
-        rowLayout.marginRight = 0;
-        rowLayout.spacing = 0;
-        rowLayout.wrap = true;
-        cCategories.setLayout(rowLayout);
-
-
-        fd = new FormData();
-        fd.top = new FormAttachment(cFilterArea, 0, SWT.CENTER);
-        lblHeader.setLayoutData(fd);
-
-        fd = new FormData();
-        fd.left = new FormAttachment(lblSep, 10);
-        fd.top = new FormAttachment(cFilterArea, 0, SWT.CENTER);
-        btnFilter.setLayoutData(fd);
-
-        fd = new FormData();
-        fd.left = new FormAttachment(lblHeader, 10);
-        fd.top = new FormAttachment(cFilterArea, 3, SWT.TOP);
-        fd.bottom = new FormAttachment(cFilterArea, -3, SWT.BOTTOM);
-        lblSep.setLayoutData(fd);
-
-        fd = new FormData();
-        fd.left = new FormAttachment(btnFilter, 0);
-        fd.right = new FormAttachment(cCategories, -10);
-        cFilterArea.setLayoutData(fd);
-
-        fd = new FormData();
-        fd.right = new FormAttachment(100, -2); 
-        fd.top = new FormAttachment(cFilterArea, 0, SWT.CENTER); 
-        fd.bottom = new FormAttachment(cFilterArea, 0, SWT.BOTTOM); 
-        cCategories.setLayoutData(fd);
-        cHeader.addListener(SWT.Resize, new Listener(){
-					public void handleEvent(Event event) {
-						if (!resizeHeaderEventQueued) {
-  		        resizeHeaderEventQueued = true;
-  						Utils.execSWTThreadLater(0, new AERunnable(){
-  							public void runSupport() {
-  								resizeHeader();
-  								resizeHeaderEventQueued = false;
-  							}
-  						});
-						}
-					}
-				});
-
-        
-        txtFilter = new Text(cFilterArea, SWT.BORDER);
-        Messages.setLanguageTooltip(txtFilter, "MyTorrentsView.filter.tooltip");
-        txtFilter.addKeyListener(this);
-        gridData = new GridData(GridData.FILL_HORIZONTAL);
-        txtFilter.setLayoutData(gridData);
-        txtFilter.addModifyListener(new ModifyListener() {
-        	public void modifyText(ModifyEvent e) {
-        		sLastSearch = ((Text)e.widget).getText();
-        		showFilterArea();
-        		updateLastSearch();
-        	}
-        });
-        txtFilter.addKeyListener(new KeyAdapter() {
-        	public void keyPressed(KeyEvent e) {
-        		if (e.keyCode == SWT.ARROW_DOWN) {
-        			tv.setFocus();
-        			e.doit = false;
-        		} else if (e.character == 13) {
-        			if (searchUpdateEvent != null) {
-        				searchUpdateEvent.cancel();
-        			}
-        			searchUpdateEvent = null;
-        			activateCategory(currentCategory);
-        		}
-        	}
-        });
-        
-
-        lblX = new Label(cFilterArea, SWT.WRAP);
-        Messages.setLanguageTooltip(lblX, "MyTorrentsView.clearFilter.tooltip");
-        gridData = new GridData(SWT.TOP);
-        lblX.setLayoutData(gridData);
-        ImageLoader.getInstance().setLabelImage(lblX, "smallx-gray");
-        lblX.setData("ImageID", "smallx-gray");
-        lblX.addMouseListener(new MouseAdapter() {
-        	public void mouseUp(MouseEvent e) {
-        		if (e.y <= 10) {
-          		sLastSearch = "";
-          		txtFilter.setText("");
-          		updateLastSearch();
-        		}
-        	}
-        });
-        
-
-        lblSep = new Label(cFilterArea, SWT.SEPARATOR | SWT.VERTICAL);
-        gridData = new GridData(GridData.FILL_VERTICAL);
-        gridData.heightHint = 5;
-        lblSep.setLayoutData(gridData);
-        
-        cHeader.moveAbove(null);
-        parent.layout(true);
+      	buildHeaderArea();
       } else {
         Control[] controls = cCategories.getChildren();
         for (int i = 0; i < controls.length; i++) {
@@ -550,11 +381,204 @@ public class MyTorrentsView
 	 *
 	 * @since 4.1.0.5
 	 */
+	private void buildHeaderArea() {
+		GridData gridData;
+    Composite parent = cTableParentPanel;
+
+    cHeader = new Composite(parent, SWT.NONE);
+    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    gridData.horizontalIndent = 5;
+    cHeader.setLayoutData(gridData);
+    cHeader.setLayout(new FormLayout());
+    FormData fd;
+    
+    lblHeader = new Label(cHeader, SWT.WRAP);
+    updateTableLabel();
+    
+    Label lblSep = new Label(cHeader, SWT.SEPARATOR | SWT.VERTICAL);
+    gridData = new GridData(GridData.FILL_VERTICAL);
+    gridData.heightHint = 5;
+    lblSep.setLayoutData(gridData);
+    
+    btnFilter = new Button(cHeader, SWT.TOGGLE);
+    Messages.setLanguageText(btnFilter, "MyTorrentsView.filter");
+    btnFilter.addSelectionListener(new SelectionListener() {
+		
+			public void widgetSelected(SelectionEvent e) {
+				boolean enable = btnFilter.getSelection();
+        cFilterArea.setVisible(enable);
+        if (enable) {
+        	tv.setFilterText(txtFilter.getText());
+        	txtFilter.setFocus();
+        } else {
+        	tv.setFilterText("");
+        	tv.setFocus();
+        }
+        resizeHeader();
+			}
+		
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+    boolean hasLastSearch = tv.getFilterText().length() != 0;
+    btnFilter.setSelection(hasLastSearch);
+    
+
+    cFilterArea = new Composite(cHeader, SWT.NONE);
+    cFilterArea.setVisible(hasLastSearch);
+    GridLayout layout = new GridLayout();
+    layout.numColumns = 5;
+    cFilterArea.setLayout(layout);
+            
+    cCategories = new Composite(cHeader, SWT.NONE);
+    RowLayout rowLayout = new RowLayout();
+    rowLayout.marginTop = 0;
+    rowLayout.marginBottom = 0;
+    rowLayout.marginLeft = 3;
+    rowLayout.marginRight = 0;
+    rowLayout.spacing = 0;
+    rowLayout.wrap = true;
+    cCategories.setLayout(rowLayout);
+    
+    cSizer = new Composite(cHeader, SWT.NONE);
+
+    fd = new FormData();
+    fd.top = new FormAttachment(cFilterArea, 0, SWT.CENTER);
+    lblHeader.setLayoutData(fd);
+
+    fd = new FormData();
+    fd.left = new FormAttachment(lblSep, 10);
+    fd.top = new FormAttachment(cFilterArea, 0, SWT.CENTER);
+    btnFilter.setLayoutData(fd);
+
+    fd = new FormData();
+    fd.left = new FormAttachment(lblHeader, 10);
+    fd.top = new FormAttachment(cFilterArea, 3, SWT.TOP);
+    fd.bottom = new FormAttachment(cFilterArea, -3, SWT.BOTTOM);
+    lblSep.setLayoutData(fd);
+
+    fd = new FormData();
+    fd.left = new FormAttachment(btnFilter, 0);
+    fd.right = new FormAttachment(cCategories, -10);
+    cFilterArea.setLayoutData(fd);
+
+    fd = new FormData();
+    fd.right = new FormAttachment(cSizer, -2); 
+    fd.top = new FormAttachment(cFilterArea, 0, SWT.CENTER); 
+    fd.bottom = new FormAttachment(cFilterArea, 0, SWT.BOTTOM); 
+    cCategories.setLayoutData(fd);
+
+		int userMode = COConfigurationManager.getIntParameter("User Mode");
+
+		boolean enableSizer = userMode >= 2 && Constants.IS_CVS_VERSION;
+		
+    fd = new FormData();
+    fd.right = new FormAttachment(100, -2); 
+    fd.top = new FormAttachment(cFilterArea, 0, SWT.CENTER); 
+    fd.width = enableSizer ? 100 : 1;
+    fd.height = enableSizer ? 18 : 1;
+    cSizer.setLayoutData(fd);
+
+    if (enableSizer) {
+    	tv.enableSizeSlider(cSizer, 16, 96);
+    }
+
+    cHeader.addListener(SWT.Resize, new Listener(){
+			public void handleEvent(Event event) {
+				if (!resizeHeaderEventQueued) {
+	        resizeHeaderEventQueued = true;
+					Utils.execSWTThreadLater(0, new AERunnable(){
+						public void runSupport() {
+							resizeHeader();
+							resizeHeaderEventQueued = false;
+						}
+					});
+				}
+			}
+		});
+    
+    
+    txtFilter = new Text(cFilterArea, SWT.BORDER);
+    Messages.setLanguageTooltip(txtFilter, "MyTorrentsView.filter.tooltip");
+    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    txtFilter.setLayoutData(gridData);
+    
+
+    lblX = new Label(cFilterArea, SWT.WRAP);
+    Messages.setLanguageTooltip(lblX, "MyTorrentsView.clearFilter.tooltip");
+    gridData = new GridData(SWT.TOP);
+    lblX.setLayoutData(gridData);
+    ImageLoader.getInstance().setLabelImage(lblX, "smallx-gray");
+    lblX.setData("ImageID", "smallx-gray");
+    lblX.addMouseListener(new MouseAdapter() {
+    	public void mouseUp(MouseEvent e) {
+    		if (e.y <= 10) {
+    			tv.setFilterText("");
+      		txtFilter.setText("");
+    		}
+    	}
+    });
+    
+
+    lblSep = new Label(cFilterArea, SWT.SEPARATOR | SWT.VERTICAL);
+    gridData = new GridData(GridData.FILL_VERTICAL);
+    gridData.heightHint = 5;
+    lblSep.setLayoutData(gridData);
+    
+    cHeader.moveAbove(null);
+    parent.layout(true);
+
+    tv.enableFilterCheck(txtFilter, this);
+	}
+
+  private void hideShowSlider() {
+  	if (!Constants.IS_CVS_VERSION) {
+  		return;
+  	}
+  	Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				int userMode = COConfigurationManager.getIntParameter("User Mode");
+				boolean isAdvanced = userMode >= 2;
+				
+				if (cSizer == null || cSizer.isDisposed()) {
+					return;
+				}
+				
+				FormData fd = (FormData) cSizer.getLayoutData();
+				if (isAdvanced) {
+					if (fd.width < 100) {
+						fd.width = 100;
+						fd.height = 16;
+			    	tv.enableSizeSlider(cSizer, 16, 96);
+			    	cSizer.setVisible(false);
+						cSizer.getParent().layout(true);
+					}
+				} else {
+					if (fd.width == 100) {
+						fd.width = 1;
+						fd.height = 1;
+						tv.disableSizeSlider();
+						cSizer.setVisible(true);
+						cSizer.getParent().layout(true);
+					}
+				}
+			}
+		});
+
+		
+	}
+
+
+	/**
+	 * 
+	 *
+	 * @since 4.1.0.5
+	 */
 	protected void showFilterArea() {
-		if (cFilterArea != null && !cFilterArea.isDisposed()) {
+		if (cFilterArea != null && !cFilterArea.isDisposed() && !cFilterArea.isVisible()) {
 			cFilterArea.setVisible(true);
 		}
-		if (btnFilter != null && !btnFilter.isDisposed()) {
+		if (btnFilter != null && !btnFilter.isDisposed() && !btnFilter.getSelection()) {
 			btnFilter.setSelection(true);
 		}
 	}
@@ -577,10 +601,10 @@ public class MyTorrentsView
 		if (onNewLine) {
 			Point prefSizeCat = cCategories.computeSize(SWT.DEFAULT, SWT.DEFAULT);
 			//System.out.println("pref=" + prefSizeCat + ";sz=" + cHeader.getClientArea());
-			if (prefSizeCat.x + posEndFilter < cHeader.getClientArea().width) {
+			if (prefSizeCat.x + posEndFilter + cSizer.getSize().x < cHeader.getClientArea().width) {
 				//System.out.println("MOVE UP");
 				FormData fd = new FormData();
-        fd.right = new FormAttachment(100, -2); 
+        fd.right = new FormAttachment(cSizer, -2); 
         fd.top = new FormAttachment(cFilterArea, 0, SWT.CENTER); 
         fd.bottom = new FormAttachment(cFilterArea, 0, SWT.BOTTOM); 
 				cCategories.setLayoutData(fd);
@@ -608,7 +632,7 @@ public class MyTorrentsView
 
 				fd = new FormData();
         fd.left = new FormAttachment(btnFilter, 0);
-        fd.right = new FormAttachment(100, -10);
+        fd.right = new FormAttachment(cSizer, -10);
         cFilterArea.setLayoutData(fd);
 
 				cHeader.getShell().layout(new Control[] {
@@ -799,7 +823,7 @@ public class MyTorrentsView
 				}
 			});
 
-			final Menu menu = new Menu(getComposite().getShell(), SWT.POP_UP);
+			final Menu menu = new Menu(catButton.getShell(), SWT.POP_UP);
 
 			catButton.setMenu(menu);
 
@@ -1126,15 +1150,13 @@ public class MyTorrentsView
 //				+ dm.getStats().getDownloadCompleted(false) + ";"
 //				+ dm.getStats().getDownloadCompleted(true));
 
-		if (bOurs) {
-			bOurs = filterCheck(dm);
-		}
-
 		return bOurs;
 	}
-	
-	public boolean filterCheck(DownloadManager dm) {
+
+	public boolean filterCheck(Object odm, String sLastSearch, boolean bRegexSearch) {
 		boolean bOurs = true;
+		DownloadManager dm = (DownloadManager) odm;
+
 		if (sLastSearch.length() > 0) {
 			try {
 				String[][] names = {
@@ -1174,6 +1196,30 @@ public class MyTorrentsView
 		}
 		return bOurs;
 	}
+	
+	// @see org.gudy.azureus2.ui.swt.views.table.TableViewFilterCheck#filterSet(java.lang.String)
+	public void filterSet(final String filter) {
+		Utils.execSWTThread(new AERunnable(){
+			public void runSupport() {
+				if (lblX != null && !lblX.isDisposed()) {
+					String oldID = (String) lblX.getData("ImageID");
+					String id = filter.length() > 0 ? "smallx" : "smallx-gray";
+					if (oldID == null || !oldID.equals(id)) {
+						ImageLoader.getInstance().setLabelImage(lblX, id);
+						lblX.setData("ImageID", id);
+					}
+				}
+
+				if (filter.length() > 0) {
+					if (txtFilter == null) {
+				    createTabs();
+					} else {
+						showFilterArea();
+					}
+				}
+			}
+		});
+	}
 
   // @see com.aelitis.azureus.ui.common.table.TableSelectionListener#selected(com.aelitis.azureus.ui.common.table.TableRowCore[])
   public void selected(TableRowCore[] rows) {
@@ -1315,14 +1361,6 @@ public class MyTorrentsView
 			// ---
 			new MenuItem(menu, SWT.SEPARATOR);
 		}
-
-		final MenuItem itemFilter = new MenuItem(menu, SWT.PUSH);
-		Messages.setLanguageText(itemFilter, "MyTorrentsView.menu.filter");
-		itemFilter.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event event) {
-				openFilterDialog();
-			}
-		});
 	}
 
 	private void createDragDrop() {
@@ -1382,14 +1420,9 @@ public class MyTorrentsView
 			dropTarget = tv.createDropTarget(DND.DROP_DEFAULT | DND.DROP_MOVE
 					| DND.DROP_COPY | DND.DROP_LINK | DND.DROP_TARGET_MOVE);
 			if (dropTarget != null) {
-				if (SWT.getVersion() >= 3107) {
-					dropTarget.setTransfer(new Transfer[] { HTMLTransfer.getInstance(),
-							URLTransfer.getInstance(), FileTransfer.getInstance(),
-							TextTransfer.getInstance() });
-				} else {
-					dropTarget.setTransfer(new Transfer[] { URLTransfer.getInstance(),
-							FileTransfer.getInstance(), TextTransfer.getInstance() });
-				}
+				dropTarget.setTransfer(new Transfer[] { HTMLTransfer.getInstance(),
+						URLTransfer.getInstance(), FileTransfer.getInstance(),
+						TextTransfer.getInstance() });
 
 				dropTarget.addDropListener(new DropTargetAdapter() {
 					public void dropAccept(DropTargetEvent event) {
@@ -1465,6 +1498,9 @@ public class MyTorrentsView
     for (int i = 0; i < rows.length; i++) {
 			TableRowCore row = rows[i];
       DownloadManager dm = (DownloadManager)row.getDataSource(true);
+      if (dm == null) {
+      	continue;
+      }
       int iOldPos = dm.getPosition();
       
       globalManager.moveTo(dm, iNewPos);
@@ -1534,10 +1570,6 @@ public class MyTorrentsView
 						e.doit = false;
 					}
 					break;
-				case 'f': // CTRL+F Find/Filter
-					openFilterDialog();
-					e.doit = false;
-					break;
 				case 'i': // CTRL+I Info/Details
 					showSelectedDetails();
 					e.doit = false;
@@ -1580,11 +1612,6 @@ public class MyTorrentsView
 							cTablePanel.getShell());
 					e.doit = false;
 					break;
-				case 'x': // CTRL+X: RegEx search switch
-					bRegexSearch = !bRegexSearch;
-					e.doit = false;
-					updateLastSearch();
-					break;
 			}
 
 			if (!e.doit)
@@ -1602,142 +1629,6 @@ public class MyTorrentsView
 			if ((e.stateMask & (~SWT.SHIFT)) != 0 || e.character < 32)
 				return;
 		}
-		
-		if (e.widget == txtFilter)
-			return;
-
-		// normal character: jump to next item with a name beginning with this character
-		if (ASYOUTYPE_MODE == ASYOUTYPE_MODE_FIND) {
-			if (System.currentTimeMillis() - lLastSearchTime > 3000)
-				sLastSearch = "";
-		}
-
-		if (e.keyCode == SWT.BS) {
-			if (e.stateMask == SWT.CONTROL)
-				sLastSearch = "";
-			else if (sLastSearch.length() > 0)
-				sLastSearch = sLastSearch.substring(0, sLastSearch.length() - 1);
-		} else
-			sLastSearch += String.valueOf(e.character);
-
-		if (ASYOUTYPE_MODE == ASYOUTYPE_MODE_FILTER) {
-			showFilterArea();
-			if (txtFilter != null && !txtFilter.isDisposed()) {
-				txtFilter.setFocus();
-			}
-			updateLastSearch();
-		} else {
-			TableCellCore[] cells = tv.getColumnCells("name");
-
-			//System.out.println(sLastSearch);
-
-			Arrays.sort(cells, TableCellImpl.TEXT_COMPARATOR);
-			int index = Arrays.binarySearch(cells, sLastSearch,
-					TableCellImpl.TEXT_COMPARATOR);
-			if (index < 0) {
-
-				int iEarliest = -1;
-				String s = bRegexSearch ? sLastSearch : "\\Q" + sLastSearch + "\\E"; 
-				Pattern pattern = Pattern.compile(s, Pattern.CASE_INSENSITIVE);
-				for (int i = 0; i < cells.length; i++) {
-					Matcher m = pattern.matcher(cells[i].getText());
-					if (m.find() && (m.start() < iEarliest || iEarliest == -1)) {
-						iEarliest = m.start();
-						index = i;
-					}
-				}
-
-				if (index < 0)
-					// Insertion Point (best guess)
-					index = -1 * index - 1;
-			}
-
-			if (index >= 0) {
-				if (index >= cells.length)
-					index = cells.length - 1;
-				TableRowCore row = cells[index].getTableRowCore();
-				int iTableIndex = row.getIndex();
-				if (iTableIndex >= 0) {
-					tv.setSelectedRows(new TableRowCore[] { row });
-				}
-			}
-			lLastSearchTime = System.currentTimeMillis();
-			updateTableLabel();
-		}
-		e.doit = false;
-	}
-
-	private void openFilterDialog() {
-		SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow();
-		entryWindow.initTexts("MyTorrentsView.dialog.setFilter.title",
-				new String[] {
-					MessageText.getString(tv.getTableID() + "View" + ".header")
-				}, "MyTorrentsView.dialog.setFilter.text", null);
-		entryWindow.setPreenteredText(sLastSearch, false);
-		entryWindow.prompt();
-		if (!entryWindow.hasSubmittedInput()) {
-			return;
-		}
-		String message = entryWindow.getSubmittedInput();
-
-		if (message == null) {
-			message = "";
-		}
-		
-		sLastSearch = message;
-		updateLastSearch();
-	}
-	
-	private void updateLastSearch() {
-		if (lblHeader == null || lblHeader.isDisposed())
-			createTabs();
-		
-		if (txtFilter != null && !txtFilter.isDisposed() && txtFilter.isVisible()) {
-			if (!sLastSearch.equals(txtFilter.getText())) {
-				txtFilter.setText(sLastSearch);
-				txtFilter.setSelection(sLastSearch.length());
-			}
-
-			if (bRegexSearch) {
-				try {
-					Pattern.compile(sLastSearch, Pattern.CASE_INSENSITIVE);
-					txtFilter.setBackground(Colors.colorAltRow);
-					Messages.setLanguageTooltip(txtFilter,
-							"MyTorrentsView.filter.tooltip");
-				} catch (Exception e) {
-					txtFilter.setBackground(Colors.colorErrorBG);
-					txtFilter.setToolTipText(e.getMessage());
-				}
-			} else {
-				txtFilter.setBackground(null);
-				Messages.setLanguageTooltip(txtFilter, "MyTorrentsView.filter.tooltip");
-			}
-		}
-		if (lblX != null && !lblX.isDisposed()) {
-
-			String oldID = (String) lblX.getData("ImageID");
-      String id = sLastSearch.length() > 0 ? "smallx" : "smallx-gray";
-      if (oldID == null || !oldID.equals(id)) {
-      	ImageLoader.getInstance().setLabelImage(lblX, id);
-      	lblX.setData("ImageID", id);
-      }
-		}
-
-		if (searchUpdateEvent != null) {
-			searchUpdateEvent.cancel();
-		}
-		searchUpdateEvent = SimpleTimer.addEvent("SearchUpdate",
-				SystemTime.getOffsetTime(ASYOUTYPE_UPDATEDELAY),
-				new TimerEventPerformer() {
-					public void perform(TimerEvent event) {
-						if (searchUpdateEvent.isCancelled()) {
-							searchUpdateEvent = null;
-							return;
-						}
-						searchUpdateEvent = null;
-						activateCategory(currentCategory);
-					}
-				});
 	}
 
 	public void keyReleased(KeyEvent e) {
@@ -1873,9 +1764,12 @@ public class MyTorrentsView
 		if (parameterName == null || parameterName.equals("MyTorrentsView.alwaysShowHeader")) {
 			setForceHeaderVisible(COConfigurationManager.getBooleanParameter("MyTorrentsView.alwaysShowHeader"));
 		}
+		if (parameterName == null || parameterName.equals("User Mode")) {
+			hideShowSlider();
+		}
 	}
 
-  private boolean top,bottom,up,down,run,start,stop,remove;
+	private boolean top,bottom,up,down,run,start,stop,remove;
 
   private void computePossibleActions() {
     Object[] dataSources = tv.getSelectedDataSources().toArray();
@@ -2065,14 +1959,14 @@ public class MyTorrentsView
 		}
 		
 		Object[] managers = globalManager.getDownloadManagers().toArray();
-		List list = tv.getDataSources();
+		Set existing = new HashSet(tv.getDataSources());
 		List listRemoves = new ArrayList();
 		List listAdds = new ArrayList();
 		
 		for (int i = 0; i < managers.length; i++) {
 			DownloadManager dm = (DownloadManager) managers[i];
 		
-			boolean bHave = list.contains(dm);
+			boolean bHave = existing.contains(dm);
 			if (!isOurDownloadManager(dm)) {
 				if (bHave) {
 					listRemoves.add(dm);
@@ -2218,7 +2112,7 @@ public class MyTorrentsView
 	protected TableViewSWT createTableView(Class forDataSourceType, String tableID,
 			TableColumnCore[] basicItems) {
 		int tableExtraStyle = COConfigurationManager.getIntParameter("MyTorrentsView.table.style");
-		return new TableViewSWTImpl(forDataSourceType, tableID, "MyTorrentsView",
+		return new TableViewSWTImpl(forDataSourceType, tableID, getPropertiesPrefix(),
 				basicItems, "#", tableExtraStyle | SWT.MULTI | SWT.FULL_SELECTION
 						| SWT.VIRTUAL) {
 			protected void setSelectedRowIndexes(int[] newSelectedRowIndices) {
diff --git a/org/gudy/azureus2/ui/swt/views/MyTrackerView.java b/org/gudy/azureus2/ui/swt/views/MyTrackerView.java
index e9d06e0..e285612 100644
--- a/org/gudy/azureus2/ui/swt/views/MyTrackerView.java
+++ b/org/gudy/azureus2/ui/swt/views/MyTrackerView.java
@@ -94,6 +94,7 @@ public class MyTrackerView
 	private TableViewSWT<TRHostTorrent> tv;
 
 	public MyTrackerView() {
+		super("MyTrackerView");
 		if (basicItems == null) {
 			basicItems = new TableColumnCore[] {
 				new NameItem(),
@@ -119,15 +120,18 @@ public class MyTrackerView
 		}
 
 		tv = new TableViewSWTImpl<TRHostTorrent>(TrackerTorrent.class,
-				TableManager.TABLE_MYTRACKER, "MyTrackerView", basicItems, "name",
+				TableManager.TABLE_MYTRACKER, getPropertiesPrefix(), basicItems, "name",
 				SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL);
-		setTableView(tv);
 		tv.addLifeCycleListener(this);
 		tv.addSelectionListener(this, false);
 		tv.addMenuFillListener(this);
 		tv.addRefreshListener(this, false);
 	}
-	
+
+  public TableViewSWT initYourTableView() {
+  	return tv;
+  }
+
 	// @see com.aelitis.azureus.ui.common.table.TableLifeCycleListener#tableViewInitialized()
 	public void tableViewInitialized() {
 		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
diff --git a/org/gudy/azureus2/ui/swt/views/PeerSuperView.java b/org/gudy/azureus2/ui/swt/views/PeerSuperView.java
index eedf33b..bdecbca 100644
--- a/org/gudy/azureus2/ui/swt/views/PeerSuperView.java
+++ b/org/gudy/azureus2/ui/swt/views/PeerSuperView.java
@@ -62,7 +62,7 @@ import com.aelitis.azureus.ui.common.table.TableLifeCycleListener;
  */
 
 public class PeerSuperView
-	extends TableViewTab
+	extends TableViewTab<PEPeer>
 	implements GlobalManagerListener, DownloadManagerPeerListener,
 	TableLifeCycleListener, TableViewSWTMenuFillListener
 {	
@@ -76,14 +76,16 @@ public class PeerSuperView
    *
    */
   public PeerSuperView() {
+  	super("AllPeersView");
+
   	TableColumnCore[] items = PeersView.getBasicColumnItems(TableManager.TABLE_ALL_PEERS);
   	TableColumnCore[] basicItems = new TableColumnCore[items.length + 1];
   	System.arraycopy(items, 0, basicItems, 0, items.length);
   	basicItems[items.length] = new DownloadNameItem(TableManager.TABLE_ALL_PEERS);
 
-  	tv = new TableViewSWTImpl<PEPeer>(Peer.class, TableManager.TABLE_ALL_PEERS, "AllPeersView",
-				basicItems, "connected_time", SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL);
-		setTableView(tv);
+  	tv = new TableViewSWTImpl<PEPeer>(Peer.class, TableManager.TABLE_ALL_PEERS,
+				getPropertiesPrefix(), basicItems, "connected_time", SWT.MULTI
+						| SWT.FULL_SELECTION | SWT.VIRTUAL);
 		tv.setRowDefaultHeight(16);
 		tv.setEnableTabViews(true);
 		tv.setCoreTabViews(new IView[] {
@@ -95,7 +97,11 @@ public class PeerSuperView
 		tv.addMenuFillListener(this);
 		
 	}	
-  
+
+  public TableViewSWT<PEPeer> initYourTableView() {
+  	return tv;
+  }
+
 	// @see com.aelitis.azureus.ui.common.table.TableLifeCycleListener#tableViewInitialized()
 	public void tableViewInitialized() {
 		shell = tv.getComposite().getShell();
diff --git a/org/gudy/azureus2/ui/swt/views/PeersView.java b/org/gudy/azureus2/ui/swt/views/PeersView.java
index 2564ea4..d02fe8d 100644
--- a/org/gudy/azureus2/ui/swt/views/PeersView.java
+++ b/org/gudy/azureus2/ui/swt/views/PeersView.java
@@ -121,10 +121,14 @@ public class PeersView
    *
    */
   public PeersView() {
+  	super("PeersView");
+  }
+  
+  // @see org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab#initYourTableView()
+  public TableViewSWT initYourTableView() {
 		tv = new TableViewSWTImpl(Peer.class, TableManager.TABLE_TORRENT_PEERS,
-				"PeersView", basicItems, "pieces", SWT.MULTI | SWT.FULL_SELECTION
+				getPropertiesPrefix(), basicItems, "pieces", SWT.MULTI | SWT.FULL_SELECTION
 						| SWT.VIRTUAL);
-		setTableView(tv);
 		tv.setRowDefaultHeight(16);
 		tv.setEnableTabViews(true);
 		tv.setCoreTabViews(new IView[] {
@@ -135,6 +139,7 @@ public class PeersView
 		tv.addTableDataSourceChangedListener(this, true);
 		tv.addLifeCycleListener(this);
 		tv.addMenuFillListener(this);
+		return tv;
 	}
   
 	public void tableDataSourceChanged(Object newDataSource) {
diff --git a/org/gudy/azureus2/ui/swt/views/PieceDistributionView.java b/org/gudy/azureus2/ui/swt/views/PieceDistributionView.java
index bac294d..d8fb551 100644
--- a/org/gudy/azureus2/ui/swt/views/PieceDistributionView.java
+++ b/org/gudy/azureus2/ui/swt/views/PieceDistributionView.java
@@ -25,8 +25,8 @@ import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.*;
+
 import org.gudy.azureus2.core3.disk.DiskManagerPiece;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
@@ -41,10 +41,12 @@ import com.aelitis.azureus.core.peermanager.piecepicker.PiecePicker;
  * @author Aaron Grunthal
  * @create 02.10.2007
  */
-public abstract class PieceDistributionView extends AbstractIView {
+public abstract class PieceDistributionView
+	extends AbstractIView
+	implements IViewExtension
+{
 	private Composite		comp;
 	private Canvas			pieceDistCanvas;
-	private GC				pieceDistGC;
 	protected PEPeerManager	pem;
 	// list of pieces that the data source has, won't be used if isMe is true
 	protected boolean[]		hasPieces;
@@ -52,6 +54,7 @@ public abstract class PieceDistributionView extends AbstractIView {
 	// instead of remote peers
 	protected boolean		isMe		= false;
 	private boolean			initialized	= false;
+	private Image imgToPaint = null;
 	
 	/**
 	 * implementors of this method must provide an appropriate peer manager and
@@ -80,17 +83,25 @@ public abstract class PieceDistributionView extends AbstractIView {
 		comp.setLayout(new FillLayout());
 		//pieceDistComposite = new Composite(parent, SWT.NONE);
 		pieceDistCanvas = new Canvas(comp,SWT.NONE);
-		pieceDistGC = new GC(pieceDistCanvas);
+		pieceDistCanvas.addListener(SWT.Paint, new Listener() {
+			public void handleEvent(Event event) {
+				if (imgToPaint != null && !imgToPaint.isDisposed()) {
+					event.gc.drawImage(imgToPaint, 0, 0);
+				}
+			}
+		});
 	}
 
 	private final void updateDistribution()
 	{
-		if (!initialized || pem.getPiecePicker() == null || pem.getDiskManager() == null)
+		if (!initialized || pem == null || comp == null
+				|| pem.getPiecePicker() == null || pem.getDiskManager() == null
+				|| !comp.isVisible())
 			return;
 		Rectangle rect = pieceDistCanvas.getBounds();
 		if (rect.height <= 0 || rect.width <= 0)
 			return;
-	
+		
 		PiecePicker picker = pem.getPiecePicker();
 		
 		final int seeds = pem.getNbSeeds() + (pem.isSeeding() ? 1 : 0);
@@ -128,7 +139,7 @@ public abstract class PieceDistributionView extends AbstractIView {
 				downloading[availabilties[i]] = true;
 		}
 		
-		Image img = new Image(pieceDistGC.getDevice(),pieceDistCanvas.getBounds());
+		Image img = new Image(comp.getDisplay(),pieceDistCanvas.getBounds());
 		
 		GC gc = new GC(img);
 
@@ -253,8 +264,11 @@ public abstract class PieceDistributionView extends AbstractIView {
 			gc.dispose();
 		}
 		
-		pieceDistGC.drawImage(img, 0, 0);
-		img.dispose();
+		if (imgToPaint != null) {
+			imgToPaint.dispose();
+		}
+		imgToPaint = img;
+		pieceDistCanvas.redraw();
 	}
 	
 	public void refresh() {
@@ -280,7 +294,19 @@ public abstract class PieceDistributionView extends AbstractIView {
 		if (!initialized)
 			return;
 		initialized = false;
-		Utils.disposeSWTObjects(new Object[] { pieceDistGC, pieceDistCanvas, comp });
+		Utils.disposeSWTObjects(new Object[] { pieceDistCanvas, comp, imgToPaint });
 		super.delete();
 	}
+	
+	public Menu getPrivateMenu() {
+		return null;
+	}
+	
+	public void viewActivated() {
+		updateDistribution();
+	}
+	
+	public void viewDeactivated() {
+		Utils.disposeSWTObjects(new Object[] { imgToPaint });
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/PiecesView.java b/org/gudy/azureus2/ui/swt/views/PiecesView.java
index ebb9e96..a5ea618 100644
--- a/org/gudy/azureus2/ui/swt/views/PiecesView.java
+++ b/org/gudy/azureus2/ui/swt/views/PiecesView.java
@@ -89,10 +89,14 @@ public class PiecesView
 	 *
 	 */
 	public PiecesView() {
+		super("PiecesView");
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab#initYourTableView()
+	public TableViewSWT initYourTableView() {
 		tv = new TableViewSWTImpl<PEPiece>(PEPiece.class,
-				TableManager.TABLE_TORRENT_PIECES, "PiecesView", basicItems,
+				TableManager.TABLE_TORRENT_PIECES, getPropertiesPrefix(), basicItems,
 				basicItems[0].getName(), SWT.SINGLE | SWT.FULL_SELECTION | SWT.VIRTUAL);
-		setTableView(tv);
 		tv.setEnableTabViews(true);
 		pieceInfoView = new PieceInfoView();
 		pieceDistView = new MyPieceDistributionView();
@@ -101,6 +105,8 @@ public class PiecesView
 		});
 		tv.addTableDataSourceChangedListener(this, true);
 		tv.addLifeCycleListener(this);
+
+		return tv;
 	}
 
 	// @see com.aelitis.azureus.ui.common.table.TableDataSourceChangedListener#tableDataSourceChanged(java.lang.Object)
diff --git a/org/gudy/azureus2/ui/swt/views/TorrentOptionsView.java b/org/gudy/azureus2/ui/swt/views/TorrentOptionsView.java
index 763aab2..a120440 100644
--- a/org/gudy/azureus2/ui/swt/views/TorrentOptionsView.java
+++ b/org/gudy/azureus2/ui/swt/views/TorrentOptionsView.java
@@ -183,7 +183,6 @@ TorrentOptionsView
 				adhoc_param_adapter, gTorrentOptions, MAX_UPLOAD);
 		adhoc_parameters.put( MAX_UPLOAD, max_upload );
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		max_upload.setLayoutData(gridData);
 		
 		if ( userMode > 0) {
@@ -200,7 +199,6 @@ TorrentOptionsView
 					DownloadManagerState.PARAM_MAX_UPLOAD_WHEN_BUSY);
 			ds_parameters.put( DownloadManagerState.PARAM_MAX_UPLOAD_WHEN_BUSY, max_upload_when_busy );
 			gridData = new GridData();
-			gridData.widthHint = 40;
 			max_upload_when_busy.setLayoutData(gridData);
 		}
 		
@@ -215,7 +213,6 @@ TorrentOptionsView
 				adhoc_param_adapter, gTorrentOptions, MAX_DOWNLOAD);
 		adhoc_parameters.put( MAX_DOWNLOAD, max_download );
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		max_download.setLayoutData(gridData);
 		
 			// max uploads
@@ -232,7 +229,6 @@ TorrentOptionsView
 			ds_parameters.put( DownloadManagerState.PARAM_MAX_UPLOADS, max_uploads );
 			max_uploads.setMinimumValue(2);
 			gridData = new GridData();
-			gridData.widthHint = 40;
 			max_uploads.setLayoutData(gridData);
 			
 				//	max uploads when seeding enabled
@@ -270,7 +266,6 @@ TorrentOptionsView
 					DownloadManagerState.PARAM_MAX_UPLOADS_WHEN_SEEDING);
 			ds_parameters.put( DownloadManagerState.PARAM_MAX_UPLOADS_WHEN_SEEDING, max_uploads_when_seeding );
 			gridData = new GridData();
-			gridData.widthHint = 40;
 			max_uploads_when_seeding.setMinimumValue(2);
 			max_uploads_when_seeding.setLayoutData(gridData);
 			
@@ -288,7 +283,6 @@ TorrentOptionsView
 					gTorrentOptions, DownloadManagerState.PARAM_MAX_PEERS);
 			ds_parameters.put( DownloadManagerState.PARAM_MAX_PEERS, max_peers );
 			gridData = new GridData();
-			gridData.widthHint = 40;
 			max_peers.setLayoutData(gridData);
 	
 				// max peers when seeding
@@ -326,7 +320,6 @@ TorrentOptionsView
 					DownloadManagerState.PARAM_MAX_PEERS_WHEN_SEEDING);
 			ds_parameters.put( DownloadManagerState.PARAM_MAX_PEERS_WHEN_SEEDING, max_peers_when_seeding );
 			gridData = new GridData();
-			gridData.widthHint = 40;
 			max_peers_when_seeding.setLayoutData(gridData);
 			
 			max_peers_when_seeding_enabled.setAdditionalActionPerformer(
@@ -345,7 +338,6 @@ TorrentOptionsView
 					DownloadManagerState.PARAM_MAX_SEEDS);
 			ds_parameters.put( DownloadManagerState.PARAM_MAX_SEEDS, max_seeds );
 			gridData = new GridData();
-			gridData.widthHint = 40;
 			max_seeds.setLayoutData(gridData);
 		}
 		
diff --git a/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsDataSource.java b/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsDataSource.java
new file mode 100644
index 0000000..b232bd7
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsDataSource.java
@@ -0,0 +1,48 @@
+package org.gudy.azureus2.ui.swt.views.clientstats;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.gudy.azureus2.core3.util.BEncodableObject;
+
+import com.aelitis.azureus.util.MapUtils;
+
+public class ClientStatsDataSource
+	implements BEncodableObject
+{
+
+	public String client;
+
+	public int count;
+
+	public int current;
+
+	public long bytesReceived;
+
+	public long bytesDiscarded;
+
+	public long bytesSent;
+
+	public ClientStatsOverall overall;
+
+	public ClientStatsDataSource() {
+	}
+
+	public ClientStatsDataSource(Map loadMap) {
+		client = MapUtils.getMapString(loadMap, "client", "?");
+		count = MapUtils.getMapInt(loadMap, "count", 0);
+		bytesReceived = MapUtils.getMapLong(loadMap, "bytesReceived", 0);
+		bytesDiscarded = MapUtils.getMapLong(loadMap, "bytesDiscarded", 0);
+		bytesSent = MapUtils.getMapLong(loadMap, "bytesSent", 0);
+	}
+
+	public Object toBencodeObject() {
+		Map<String, Object> map = new HashMap<String, Object>();
+		map.put("client", client);
+		map.put("count", Long.valueOf(count));
+		map.put("bytesReceived", Long.valueOf(bytesReceived));
+		map.put("bytesDiscarded", Long.valueOf(bytesDiscarded));
+		map.put("bytesSent", Long.valueOf(bytesSent));
+		return map;
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsOverall.java b/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsOverall.java
new file mode 100644
index 0000000..182ab68
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsOverall.java
@@ -0,0 +1,50 @@
+/**
+ * Created on Oct 24, 2009
+ *
+ * Copyright 2008 Vuze, Inc.  All rights reserved.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
+ */
+ 
+package org.gudy.azureus2.ui.swt.views.clientstats;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.aelitis.azureus.util.MapUtils;
+
+/**
+ * @author TuxPaper
+ * @created Oct 24, 2009
+ *
+ */
+public class ClientStatsOverall
+{
+	long count;
+	
+	public ClientStatsOverall() {
+	}
+
+	public ClientStatsOverall(Map loadMap) {
+		if (loadMap == null) {
+			return;
+		}
+		count = MapUtils.getMapLong(loadMap, "count", 0);
+	}
+
+	public Map<String, Object> toMap() {
+		Map<String, Object> map = new HashMap<String, Object>();
+		map.put("count", Long.valueOf(count));
+		return map;
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsView.java b/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsView.java
new file mode 100644
index 0000000..18853ea
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsView.java
@@ -0,0 +1,580 @@
+package org.gudy.azureus2.ui.swt.views.clientstats;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.download.DownloadManagerPeerListener;
+import org.gudy.azureus2.core3.global.GlobalManagerListener;
+import org.gudy.azureus2.core3.peer.PEPeer;
+import org.gudy.azureus2.core3.peer.PEPeerListener;
+import org.gudy.azureus2.core3.peer.PEPeerManager;
+import org.gudy.azureus2.core3.util.*;
+
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+import org.gudy.azureus2.plugins.ui.tables.TableColumnCreationListener;
+import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
+import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab;
+import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.core.peermanager.piecepicker.util.BitFlags;
+import com.aelitis.azureus.core.util.bloom.BloomFilter;
+import com.aelitis.azureus.core.util.bloom.BloomFilterFactory;
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.common.table.TableLifeCycleListener;
+import com.aelitis.azureus.ui.common.table.TableRowCore;
+import com.aelitis.azureus.util.MapUtils;
+
+public class ClientStatsView
+	extends TableViewTab<ClientStatsDataSource>
+	implements TableLifeCycleListener, GlobalManagerListener,
+	DownloadManagerPeerListener
+{
+	private static final String CONFIG_FILE = "ClientStats.dat";
+
+	private static final String CONFIG_FILE_ARCHIVE = "ClientStats_%1.dat";
+
+	private static final int BLOOMFILTER_SIZE = 100000;
+
+	private static final int BLOOMFILTER_PEERID_SIZE = 50000;
+
+	private static final String TABLEID = "ClientStats";
+
+	private AzureusCore core;
+
+	private TableViewSWTImpl<ClientStatsDataSource> tv;
+
+	private boolean columnsAdded;
+
+	private Map<String, ClientStatsDataSource> mapData;
+
+	private Composite parent;
+
+	private BloomFilter bloomFilter;
+
+	private BloomFilter bloomFilterPeerId;
+
+	private ClientStatsOverall overall;
+
+	private long startedListeningOn;
+
+	private long totalTime;
+
+	private long lastAdd;
+
+	private GregorianCalendar calendar = new GregorianCalendar();
+
+	private int lastAddMonth;
+
+	public ClientStatsView() {
+		super("ClientStats");
+
+		initAndLoad();
+
+		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+			public void azureusCoreRunning(AzureusCore core) {
+				initColumns(core);
+			}
+		});
+	}
+
+	public Composite initComposite(Composite composite) {
+		parent = new Composite(composite, SWT.BORDER);
+		parent.setLayout(new FormLayout());
+		Layout layout = composite.getLayout();
+		if (layout instanceof GridLayout) {
+			parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+		} else if (layout instanceof FormLayout) {
+			parent.setLayoutData(Utils.getFilledFormData());
+		}
+
+		return parent;
+	}
+
+	public void tableViewTabInitComplete() {
+		Composite cTV = (Composite) parent.getChildren()[0];
+		Composite cBottom = new Composite(parent, SWT.None);
+		FormData fd;
+		fd = Utils.getFilledFormData();
+		fd.bottom = new FormAttachment(cBottom);
+		cTV.setLayoutData(fd);
+		fd = Utils.getFilledFormData();
+		fd.top = null;
+		cBottom.setLayoutData(fd);
+		cBottom.setLayout(new FormLayout());
+
+		Button btnCopy = new Button(cBottom, SWT.PUSH);
+		btnCopy.setLayoutData(new FormData());
+		btnCopy.setText("Copy");
+		btnCopy.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				TableRowCore[] rows = tv.getRows();
+				StringBuilder sb = new StringBuilder();
+
+				sb.append(new SimpleDateFormat("MMM yyyy").format(new Date()));
+				sb.append("\n");
+
+				sb.append("Hits,Client,Bytes Sent,Bytes Received,Bad Bytes\n");
+				for (TableRowCore row : rows) {
+					ClientStatsDataSource stat = (ClientStatsDataSource) row.getDataSource();
+					if (stat == null) {
+						continue;
+					}
+					sb.append(stat.count);
+					sb.append(",");
+					sb.append(stat.client.replaceAll(",", ""));
+					sb.append(",");
+					sb.append(stat.bytesSent);
+					sb.append(",");
+					sb.append(stat.bytesReceived);
+					sb.append(",");
+					sb.append(stat.bytesDiscarded);
+					sb.append("\n");
+				}
+				ClipboardCopy.copyToClipBoard(sb.toString());
+			}
+		});
+
+		Button btnCopyShort = new Button(cBottom, SWT.PUSH);
+		btnCopyShort.setLayoutData(new FormData());
+		btnCopyShort.setText("Copy > 1%");
+		btnCopyShort.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				StringBuilder sb = new StringBuilder();
+
+				sb.append(new SimpleDateFormat("MMM ''yy").format(new Date()));
+				sb.append("] ");
+				sb.append(overall.count);
+				sb.append(": ");
+
+				ClientStatsDataSource[] stats = mapData.values().toArray(
+						new ClientStatsDataSource[0]);
+				Arrays.sort(stats, new Comparator<ClientStatsDataSource>() {
+					public int compare(ClientStatsDataSource o1, ClientStatsDataSource o2) {
+						if (o1.count == o2.count) {
+							return 0;
+						}
+						return o1.count > o2.count ? -1 : 1;
+					}
+				});
+
+				boolean first = true;
+				for (ClientStatsDataSource stat : stats) {
+					int pct = (int) (stat.count * 1000 / overall.count);
+					if (pct < 10) {
+						continue;
+					}
+					if (first) {
+						first = false;
+					} else {
+						sb.append(", ");
+					}
+					sb.append(DisplayFormatters.formatPercentFromThousands(pct));
+					sb.append(" ");
+					sb.append(stat.client);
+				}
+
+				Arrays.sort(stats, new Comparator<ClientStatsDataSource>() {
+					public int compare(ClientStatsDataSource o1, ClientStatsDataSource o2) {
+						float v1 = (float) o1.bytesReceived / o1.count;
+						float v2 = (float) o2.bytesReceived / o2.count;
+						if (v1 == v2) {
+							return 0;
+						}
+						return v1 > v2 ? -1 : 1;
+					}
+				});
+				int top = 5;
+				first = true;
+				sb.append("\nBest Seeders (");
+				long total = 0;
+				for (ClientStatsDataSource stat : stats) {
+					total += stat.bytesReceived;
+				}
+				sb.append(DisplayFormatters.formatByteCountToKiBEtc(total, false, true,
+						0));
+				sb.append(" Downloaded): ");
+				for (ClientStatsDataSource stat : stats) {
+					if (first) {
+						first = false;
+					} else {
+						sb.append(", ");
+					}
+					sb.append(DisplayFormatters.formatByteCountToKiBEtc(
+							stat.bytesReceived / stat.count, false, true, 0));
+					sb.append(" per ");
+					sb.append(stat.client);
+					sb.append("(x");
+					sb.append(stat.count);
+					sb.append(")");
+					if (--top <= 0) {
+						break;
+					}
+				}
+
+				ClipboardCopy.copyToClipBoard(sb.toString());
+			}
+		});
+		fd = new FormData();
+		fd.left = new FormAttachment(btnCopy, 5);
+		btnCopyShort.setLayoutData(fd);
+	}
+
+	public TableViewSWT<ClientStatsDataSource> initYourTableView() {
+		tv = new TableViewSWTImpl<ClientStatsDataSource>(
+				ClientStatsDataSource.class, TABLEID, getPropertiesPrefix(),
+				new TableColumnCore[0], ColumnCS_Count.COLUMN_ID, SWT.MULTI
+						| SWT.FULL_SELECTION | SWT.VIRTUAL);
+		/*
+				tv.addTableDataSourceChangedListener(this, true);
+				tv.addRefreshListener(this, true);
+				tv.addSelectionListener(this, false);
+				tv.addMenuFillListener(this);
+				*/
+		tv.addLifeCycleListener(this);
+
+		return tv;
+	}
+
+	private void initColumns(AzureusCore core) {
+		synchronized (ClientStatsView.class) {
+
+			if (columnsAdded) {
+
+				return;
+			}
+
+			columnsAdded = true;
+		}
+
+		UIManager uiManager = PluginInitializer.getDefaultInterface().getUIManager();
+
+		TableManager tableManager = uiManager.getTableManager();
+
+		tableManager.registerColumn(ClientStatsDataSource.class,
+				ColumnCS_Name.COLUMN_ID, new TableColumnCreationListener() {
+					public void tableColumnCreated(TableColumn column) {
+						new ColumnCS_Name(column);
+					}
+				});
+		tableManager.registerColumn(ClientStatsDataSource.class,
+				ColumnCS_Count.COLUMN_ID, new TableColumnCreationListener() {
+					public void tableColumnCreated(TableColumn column) {
+						new ColumnCS_Count(column);
+					}
+				});
+		tableManager.registerColumn(ClientStatsDataSource.class,
+				ColumnCS_Discarded.COLUMN_ID, new TableColumnCreationListener() {
+					public void tableColumnCreated(TableColumn column) {
+						new ColumnCS_Discarded(column);
+					}
+				});
+		tableManager.registerColumn(ClientStatsDataSource.class,
+				ColumnCS_Received.COLUMN_ID, new TableColumnCreationListener() {
+					public void tableColumnCreated(TableColumn column) {
+						new ColumnCS_Received(column);
+					}
+				});
+		tableManager.registerColumn(ClientStatsDataSource.class,
+				ColumnCS_Sent.COLUMN_ID, new TableColumnCreationListener() {
+					public void tableColumnCreated(TableColumn column) {
+						new ColumnCS_Sent(column);
+					}
+				});
+		tableManager.registerColumn(ClientStatsDataSource.class,
+				ColumnCS_Pct.COLUMN_ID, new TableColumnCreationListener() {
+					public void tableColumnCreated(TableColumn column) {
+						new ColumnCS_Pct(column);
+					}
+				});
+		
+		TableColumnManager tcManager = TableColumnManager.getInstance();
+		tcManager.setDefaultColumnNames(TABLEID, new String[] {
+			ColumnCS_Name.COLUMN_ID,
+			ColumnCS_Pct.COLUMN_ID,
+			ColumnCS_Count.COLUMN_ID,
+			ColumnCS_Received.COLUMN_ID,
+			ColumnCS_Sent.COLUMN_ID,
+			ColumnCS_Discarded.COLUMN_ID,
+		});
+	}
+
+	public void tableViewDestroyed() {
+		if (core == null) {
+			// not initialized, skip save
+			return;
+		}
+		core.getGlobalManager().removeListener(this);
+		List downloadManagers = core.getGlobalManager().getDownloadManagers();
+		for (Object object : downloadManagers) {
+			((DownloadManager) object).removePeerListener(this);
+		}
+		save(CONFIG_FILE);
+	}
+
+	private void initAndLoad() {
+		mapData = new HashMap<String, ClientStatsDataSource>();
+
+		synchronized (mapData) {
+			Map map = FileUtil.readResilientConfigFile(CONFIG_FILE);
+
+			totalTime = MapUtils.getMapLong(map, "time", 0);
+
+			lastAdd = MapUtils.getMapLong(map, "lastadd", 0);
+			if (lastAdd != 0) {
+				calendar.setTimeInMillis(lastAdd);
+				lastAddMonth = calendar.get(Calendar.MONTH);
+
+				Map mapBloom = MapUtils.getMapMap(map, "bloomfilter", null);
+				if (mapBloom != null) {
+					bloomFilter = BloomFilterFactory.deserialiseFromMap(mapBloom);
+				}
+				mapBloom = MapUtils.getMapMap(map, "bloomfilterPeerId", null);
+				if (mapBloom != null) {
+					bloomFilterPeerId = BloomFilterFactory.deserialiseFromMap(mapBloom);
+				}
+			}
+			if (bloomFilter == null) {
+				bloomFilter = BloomFilterFactory.createRotating(
+						BloomFilterFactory.createAddOnly(BLOOMFILTER_SIZE), 2);
+			}
+			if (bloomFilterPeerId == null) {
+				bloomFilterPeerId = BloomFilterFactory.createRotating(
+						BloomFilterFactory.createAddOnly(BLOOMFILTER_PEERID_SIZE), 2);
+			}
+
+			overall = new ClientStatsOverall();
+
+			List listSavedData = MapUtils.getMapList(map, "data", null);
+			if (listSavedData != null) {
+				for (Object val : listSavedData) {
+					try {
+						Map mapVal = (Map) val;
+						if (mapVal != null) {
+							ClientStatsDataSource ds = new ClientStatsDataSource(mapVal);
+							ds.overall = overall;
+
+							if (!mapData.containsKey(ds.client)) {
+								mapData.put(ds.client, ds);
+								overall.count += ds.count;
+							}
+						}
+
+					} catch (Exception e) {
+						// ignore
+					}
+				}
+			}
+		}
+	}
+
+	private void save(String filename) {
+		Map<String, Object> map = new HashMap<String, Object>();
+		synchronized (mapData) {
+			map.put("data", new ArrayList(mapData.values()));
+			map.put("bloomfilter", bloomFilter.serialiseToMap());
+			map.put("bloomfilterPeerId", bloomFilterPeerId.serialiseToMap());
+			map.put("lastadd", SystemTime.getCurrentTime());
+			if (startedListeningOn > 0) {
+				map.put("time", totalTime
+						+ (SystemTime.getCurrentTime() - startedListeningOn));
+			} else {
+				map.put("time", totalTime);
+			}
+		}
+		FileUtil.writeResilientConfigFile(filename, map);
+	}
+
+	public void tableViewInitialized() {
+		synchronized (mapData) {
+			if (mapData.values().size() > 0) {
+				tv.addDataSources(mapData.values().toArray(new ClientStatsDataSource[0]));
+			}
+		}
+		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+
+			public void azureusCoreRunning(AzureusCore core) {
+				register(core);
+			}
+		});
+	}
+
+	protected void register(AzureusCore core) {
+		this.core = core;
+		core.getGlobalManager().addListener(this);
+		startedListeningOn = SystemTime.getCurrentTime();
+	}
+
+	public void destroyInitiated() {
+	}
+
+	public void destroyed() {
+	}
+
+	public void downloadManagerAdded(DownloadManager dm) {
+		dm.addPeerListener(this, true);
+	}
+
+	public void downloadManagerRemoved(DownloadManager dm) {
+		dm.removePeerListener(this);
+	}
+
+	public void seedingStatusChanged(boolean seedingOnlyMode,
+			boolean potentiallySeedingOnlyMode) {
+	}
+
+	public void peerAdded(PEPeer peer) {
+		peer.addListener(new PEPeerListener() {
+
+			public void stateChanged(PEPeer peer, int newState) {
+				if (newState == PEPeer.TRANSFERING) {
+					addPeer(peer);
+				} else if (newState == PEPeer.CLOSING
+						|| newState == PEPeer.DISCONNECTED) {
+					peer.removeListener(this);
+				}
+			}
+
+			public void sentBadChunk(PEPeer peer, int pieceNum, int totalBadChunks) {
+			}
+
+			public void removeAvailability(PEPeer peer, BitFlags peerHavePieces) {
+			}
+
+			public void addAvailability(PEPeer peer, BitFlags peerHavePieces) {
+			}
+		});
+	}
+
+	protected void addPeer(PEPeer peer) {
+		byte[] bloomId;
+		long now = SystemTime.getCurrentTime();
+
+		// Bloom Filter is based on the first 8 bytes of peer id + ip address
+		// This captures more duplicates than peer id because most clients
+		// randomize their peer id on restart.  IP address, however, changes
+		// less often.
+		byte[] peerId = peer.getId();
+		InetAddress ip = peer.getAlternativeIPv6();
+		if (ip == null) {
+			try {
+				ip = InetAddress.getByName(peer.getIp());
+			} catch (UnknownHostException e) {
+			}
+		}
+		if (ip == null) {
+			bloomId = peerId;
+		} else {
+			byte[] address = ip.getAddress();
+			bloomId = new byte[8 + address.length];
+			System.arraycopy(peerId, 0, bloomId, 0, 8);
+			System.arraycopy(address, 0, bloomId, 8, address.length);
+		}
+
+		synchronized (mapData) {
+			// break on month.. assume user didn't last use this on the same month in a different year
+			calendar.setTimeInMillis(now);
+			int thisMonth = calendar.get(Calendar.MONTH);
+			if (thisMonth != lastAddMonth) {
+				if (lastAddMonth == 0) {
+					lastAddMonth = thisMonth;
+				} else {
+					String s = new SimpleDateFormat("yyyy-MM").format(new Date(lastAdd));
+					String filename = CONFIG_FILE_ARCHIVE.replace("%1", s);
+					save(filename);
+
+					lastAddMonth = thisMonth;
+					lastAdd = 0;
+					bloomFilter = BloomFilterFactory.createRotating(
+							BloomFilterFactory.createAddOnly(BLOOMFILTER_SIZE), 2);
+					bloomFilterPeerId = BloomFilterFactory.createRotating(
+							BloomFilterFactory.createAddOnly(BLOOMFILTER_PEERID_SIZE), 2);
+					overall = new ClientStatsOverall();
+					mapData.clear();
+					tv.removeAllTableRows();
+					totalTime = 0;
+					startedListeningOn = 0;
+				}
+			}
+
+			if (bloomFilter.contains(bloomId) || bloomFilterPeerId.contains(peerId)) {
+				return;
+			}
+
+			bloomFilter.add(bloomId);
+			bloomFilterPeerId.add(peerId);
+
+			lastAdd = now;
+
+			String id = getID(peer);
+			ClientStatsDataSource stat = mapData.get(id);
+			boolean needNew = stat == null;
+			if (needNew) {
+				stat = new ClientStatsDataSource();
+				stat.overall = overall;
+				mapData.put(id, stat);
+			}
+
+			overall.count++;
+
+			stat.client = getID(peer);
+			stat.count++;
+			stat.current++;
+			if (needNew) {
+				tv.addDataSource(stat);
+			} else {
+				TableRowCore row = tv.getRow(stat);
+				if (row != null) {
+					row.invalidate();
+				}
+			}
+		}
+	}
+
+	public void peerManagerAdded(PEPeerManager manager) {
+	}
+
+	public void peerManagerRemoved(PEPeerManager manager) {
+	}
+
+	public void peerManagerWillBeAdded(PEPeerManager manager) {
+	}
+
+	public void peerRemoved(PEPeer peer) {
+		synchronized (mapData) {
+			ClientStatsDataSource stat = mapData.get(getID(peer));
+			if (stat != null) {
+				stat.current--;
+				stat.bytesReceived += peer.getStats().getTotalDataBytesReceived();
+				stat.bytesSent += peer.getStats().getTotalDataBytesSent();
+				stat.bytesDiscarded += peer.getStats().getTotalBytesDiscarded();
+
+				TableRowCore row = tv.getRow(stat);
+				if (row != null) {
+					row.invalidate();
+				}
+			}
+		}
+	}
+
+	private String getID(PEPeer peer) {
+		String s = peer.getClient();
+		return s.replaceAll(" v?[0-9._]+", "");
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Count.java b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Count.java
new file mode 100644
index 0000000..3a1f94f
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Count.java
@@ -0,0 +1,27 @@
+package org.gudy.azureus2.ui.swt.views.clientstats;
+
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+public class ColumnCS_Count
+	implements TableCellRefreshListener
+{
+
+	public static final String COLUMN_ID = "count";
+
+	public ColumnCS_Count(TableColumn column) {
+		column.initialize(TableColumn.ALIGN_TRAIL, TableColumn.POSITION_LAST, 50);
+		column.addListeners(this);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+	}
+
+	public void refresh(TableCell cell) {
+		ClientStatsDataSource ds = (ClientStatsDataSource) cell.getDataSource();
+		if (ds == null) {
+			return;
+		}
+		long val = ds.count;
+		if (cell.setSortValue(val) || !cell.isValid()) {
+			cell.setText(Long.toString(val));
+		}
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Discarded.java b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Discarded.java
new file mode 100644
index 0000000..232704f
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Discarded.java
@@ -0,0 +1,30 @@
+package org.gudy.azureus2.ui.swt.views.clientstats;
+
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+
+public class ColumnCS_Discarded
+	implements TableCellRefreshListener
+{
+
+	public static final String COLUMN_ID = "discarded";
+
+	public ColumnCS_Discarded(TableColumn column) {
+		column.initialize(TableColumn.ALIGN_TRAIL, TableColumn.POSITION_LAST, 80);
+		column.addListeners(this);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+	}
+
+	public void refresh(TableCell cell) {
+		ClientStatsDataSource ds = (ClientStatsDataSource) cell.getDataSource();
+		if (ds == null) {
+			return;
+		}
+		long val = ds.bytesDiscarded;
+		if (cell.setSortValue(val) || !cell.isValid()) {
+			cell.setText(DisplayFormatters.formatByteCountToKiBEtc(val));
+		}
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Name.java b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Name.java
new file mode 100644
index 0000000..6dce82d
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Name.java
@@ -0,0 +1,27 @@
+package org.gudy.azureus2.ui.swt.views.clientstats;
+
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+
+public class ColumnCS_Name
+	implements TableCellRefreshListener
+{
+
+	public static final String COLUMN_ID = "name";
+
+	public ColumnCS_Name(TableColumn column) {
+		column.initialize(TableColumn.ALIGN_LEAD, TableColumn.POSITION_LAST, 215);
+		column.addListeners(this);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+	}
+
+	public void refresh(TableCell cell) {
+		ClientStatsDataSource ds = (ClientStatsDataSource) cell.getDataSource();
+		if (ds == null) {
+			return;
+		}
+		cell.setText(ds.client);
+	}
+
+}
diff --git a/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Pct.java b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Pct.java
new file mode 100644
index 0000000..25fa92d
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Pct.java
@@ -0,0 +1,32 @@
+package org.gudy.azureus2.ui.swt.views.clientstats;
+
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+
+public class ColumnCS_Pct
+	implements TableCellRefreshListener
+{
+
+	public static final String COLUMN_ID = "percent";
+
+	public ColumnCS_Pct(TableColumn column) {
+		column.initialize(TableColumn.ALIGN_TRAIL, TableColumn.POSITION_LAST, 50);
+		column.addListeners(this);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+		column.setRefreshInterval(TableColumn.INTERVAL_LIVE);
+	}
+
+	public void refresh(TableCell cell) {
+		ClientStatsDataSource ds = (ClientStatsDataSource) cell.getDataSource();
+		if (ds == null) {
+			return;
+		}
+		float val = ds.count * 1000f / ds.overall.count;
+		if (cell.setSortValue(val) || !cell.isValid()) {
+			cell.setText(DisplayFormatters.formatPercentFromThousands((int) val));
+		}
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Received.java b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Received.java
new file mode 100644
index 0000000..e205461
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Received.java
@@ -0,0 +1,30 @@
+package org.gudy.azureus2.ui.swt.views.clientstats;
+
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+
+public class ColumnCS_Received
+	implements TableCellRefreshListener
+{
+
+	public static final String COLUMN_ID = "received";
+
+	public ColumnCS_Received(TableColumn column) {
+		column.initialize(TableColumn.ALIGN_TRAIL, TableColumn.POSITION_LAST, 80);
+		column.addListeners(this);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+	}
+
+	public void refresh(TableCell cell) {
+		ClientStatsDataSource ds = (ClientStatsDataSource) cell.getDataSource();
+		if (ds == null) {
+			return;
+		}
+		long val = ds.bytesReceived;
+		if (cell.setSortValue(val) || !cell.isValid()) {
+			cell.setText(DisplayFormatters.formatByteCountToKiBEtc(val));
+		}
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Sent.java b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Sent.java
new file mode 100644
index 0000000..b605370
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/clientstats/ColumnCS_Sent.java
@@ -0,0 +1,30 @@
+package org.gudy.azureus2.ui.swt.views.clientstats;
+
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+
+public class ColumnCS_Sent
+	implements TableCellRefreshListener
+{
+
+	public static final String COLUMN_ID = "sent";
+
+	public ColumnCS_Sent(TableColumn column) {
+		column.initialize(TableColumn.ALIGN_TRAIL, TableColumn.POSITION_LAST, 80);
+		column.addListeners(this);
+		column.setType(TableColumn.TYPE_TEXT_ONLY);
+	}
+
+	public void refresh(TableCell cell) {
+		ClientStatsDataSource ds = (ClientStatsDataSource) cell.getDataSource();
+		if (ds == null) {
+			return;
+		}
+		long val = ds.bytesSent;
+		if (cell.setSortValue(val) || !cell.isValid()) {
+			cell.setText(DisplayFormatters.formatByteCountToKiBEtc(val));
+		}
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/columnsetup/TableColumnSetupWindow.java b/org/gudy/azureus2/ui/swt/views/columnsetup/TableColumnSetupWindow.java
index 990efc9..db7ed0f 100644
--- a/org/gudy/azureus2/ui/swt/views/columnsetup/TableColumnSetupWindow.java
+++ b/org/gudy/azureus2/ui/swt/views/columnsetup/TableColumnSetupWindow.java
@@ -19,6 +19,7 @@
 package org.gudy.azureus2.ui.swt.views.columnsetup;
 
 import java.util.*;
+import java.util.List;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.*;
@@ -103,6 +104,8 @@ public class TableColumnSetupWindow
 
 	private Group cPickArea;
 
+	protected boolean doReset;
+
 	public TableColumnSetupWindow(final Class forDataSourceType, String _tableID,
 			TableRow sampleRow, TableStructureModificationListener _listener) {
 		this.sampleRow = sampleRow;
@@ -234,12 +237,9 @@ public class TableColumnSetupWindow
 		Group cResultArea = new Group(shell, SWT.NONE);
 		Messages.setLanguageText(cResultArea, "ColumnSetup.chosencolumns");
 		cResultArea.setLayout(new FormLayout());
-		fd = new FormData();
-		fd.top = new FormAttachment(topInfo, 5);
-		fd.right = new FormAttachment(100, -3);
-		fd.bottom = new FormAttachment(btnOk, -5);
-		fd.width = 200;
-		cResultArea.setLayoutData(fd);
+		
+		Composite cResultButtonArea = new Composite(cResultArea, SWT.NONE);
+		cResultButtonArea.setLayout(new FormLayout());
 
 		tvAvail = createTVAvail();
 
@@ -415,7 +415,7 @@ public class TableColumnSetupWindow
 
 		ImageLoader imageLoader = ImageLoader.getInstance();
 
-		Button btnUp = new Button(cResultArea, SWT.PUSH);
+		Button btnUp = new Button(cResultButtonArea, SWT.PUSH);
 		imageLoader.setButtonImage(btnUp, "up");
 		btnUp.addSelectionListener(new SelectionListener() {
 			public void widgetSelected(SelectionEvent e) {
@@ -426,7 +426,7 @@ public class TableColumnSetupWindow
 			}
 		});
 
-		Button btnDown = new Button(cResultArea, SWT.PUSH);
+		Button btnDown = new Button(cResultButtonArea, SWT.PUSH);
 		imageLoader.setButtonImage(btnDown, "down");
 		btnDown.addSelectionListener(new SelectionListener() {
 			public void widgetSelected(SelectionEvent e) {
@@ -437,7 +437,7 @@ public class TableColumnSetupWindow
 			}
 		});
 
-		Button btnDel = new Button(cResultArea, SWT.PUSH);
+		Button btnDel = new Button(cResultButtonArea, SWT.PUSH);
 		imageLoader.setButtonImage(btnDel, "delete");
 		btnDel.addSelectionListener(new SelectionListener() {
 			public void widgetSelected(SelectionEvent e) {
@@ -475,6 +475,41 @@ public class TableColumnSetupWindow
 		}
 		tvChosen.processDataSourceQueue();
 
+		
+		Button btnReset = null;
+		String[] defaultColumnNames = tcm.getDefaultColumnNames(forTableID);
+		if (defaultColumnNames != null) {
+  		btnReset = new Button(cResultButtonArea, SWT.PUSH);
+  		Messages.setLanguageText(btnReset, "Button.reset");
+  		btnReset.addSelectionListener(new SelectionAdapter() {
+  			public void widgetSelected(SelectionEvent e) {
+  				String[] defaultColumnNames = tcm.getDefaultColumnNames(forTableID);
+  				if (defaultColumnNames != null) {
+  					List<TableColumnCore> defaultColumns = new ArrayList<TableColumnCore>();
+  					for (String name : defaultColumnNames) {
+  						TableColumnCore column = tcm.getTableColumnCore(forTableID, name);
+  						if (column != null) {
+  							defaultColumns.add(column);
+  						}
+						}
+  					if (defaultColumns.size() > 0) {
+  						for (TableColumnCore tc : mapNewVisibility.keySet()) {
+								mapNewVisibility.put(tc, Boolean.FALSE);
+							}
+  						tvChosen.removeAllTableRows();
+  						columnsChosen = defaultColumns.toArray(new TableColumnCore[0]);
+  						for (int i = 0; i < columnsChosen.length; i++) {
+  							mapNewVisibility.put(columnsChosen[i], Boolean.TRUE);
+								columnsChosen[i].setPositionNoShift(i);
+								tvChosen.addDataSource(columnsChosen[i]);
+  						}
+  						doReset = true;
+  					}
+  				}
+  			}
+  		});
+		}
+		
 		Button btnCancel = new Button(shell, SWT.PUSH);
 		Messages.setLanguageText(btnCancel, "Button.cancel");
 		btnCancel.addSelectionListener(new SelectionAdapter() {
@@ -483,7 +518,7 @@ public class TableColumnSetupWindow
 			}
 		});
 
-		Button btnApply = new Button(shell, SWT.PUSH);
+		Button btnApply = new Button(cResultButtonArea, SWT.PUSH);
 		Messages.setLanguageText(btnApply, "Button.apply");
 		btnApply.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent e) {
@@ -498,8 +533,21 @@ public class TableColumnSetupWindow
 		//lblChosenHeader.setLayoutData(fd);
 
 		fd = new FormData();
+		fd.top = new FormAttachment(topInfo, 5);
+		fd.right = new FormAttachment(100, -3);
+		fd.bottom = new FormAttachment(btnOk, -5);
+		fd.width = 200;
+		cResultArea.setLayoutData(fd);
+		
+		fd = new FormData();
+		fd.bottom = new FormAttachment(100, 0);
+		fd.left = new FormAttachment(cTableChosen, 0, SWT.CENTER);
+		//fd.right = new FormAttachment(100, 0);
+		cResultButtonArea.setLayoutData(fd);
+
+		fd = new FormData();
 		fd.right = new FormAttachment(btnDown, -5);
-		fd.bottom = new FormAttachment(100, -3);
+		fd.bottom = new FormAttachment(btnApply, -3);
 		btnUp.setLayoutData(fd);
 
 		fd = new FormData();
@@ -519,24 +567,31 @@ public class TableColumnSetupWindow
 		fd.left = new FormAttachment(0, 0);
 		fd.right = new FormAttachment(100, 0);
 		//fd.bottom = new FormAttachment(100, 0);
-		fd.bottom = new FormAttachment(btnUp, -3);
+		fd.bottom = new FormAttachment(cResultButtonArea, -3, SWT.TOP);
 		cTableChosen.setLayoutData(fd);
+		
+		if (btnReset != null) {
+  		fd = new FormData();
+  		fd.right = new FormAttachment(btnApply, -3);
+  		fd.bottom = new FormAttachment(btnApply, 0, SWT.BOTTOM);
+  		btnReset.setLayoutData(fd);
+		}
 
 		fd = new FormData();
-		fd.right = new FormAttachment(100, -8);
+		fd.right = new FormAttachment(100, -5);
 		fd.bottom = new FormAttachment(100, -3);
 		//fd.width = 64;
 		btnApply.setLayoutData(fd);
 
 		fd = new FormData();
-		fd.right = new FormAttachment(btnApply, -3);
-		fd.bottom = new FormAttachment(btnApply, 0, SWT.BOTTOM);
+		fd.right = new FormAttachment(100, -8);
+		fd.bottom = new FormAttachment(100, -3);
 		//fd.width = 65;
 		btnCancel.setLayoutData(fd);
 
 		fd = new FormData();
 		fd.right = new FormAttachment(btnCancel, -3);
-		fd.bottom = new FormAttachment(btnApply, 0, SWT.BOTTOM);
+		fd.bottom = new FormAttachment(btnCancel, 0, SWT.BOTTOM);
 		//fd.width = 64;
 		btnOk.setLayoutData(fd);
 
@@ -606,7 +661,6 @@ public class TableColumnSetupWindow
 			cResultArea,
 			btnOk,
 			btnCancel,
-			btnApply
 		});
 
 		cPickArea.setTabList(new Control[] {
@@ -782,10 +836,11 @@ public class TableColumnSetupWindow
 	 * @since 4.0.0.5
 	 */
 	protected void apply() {
-		for (int i = 0; i < columnsChosen.length; i++) {
-			TableColumnCore column = columnsChosen[i];
-			if (column != null) {
-				column.setVisible(mapNewVisibility.get(column).booleanValue());
+		for (TableColumnCore tc : mapNewVisibility.keySet()) {
+			boolean visible = mapNewVisibility.get(tc).booleanValue();
+			tc.setVisible(visible);
+			if (doReset) {
+				tc.reset();
 			}
 		}
 		TableColumnManager.getInstance().saveTableColumns(forDataSourceType,
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java
index 5fa1571..00171c7 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java
@@ -104,7 +104,6 @@ public class ConfigSectionConnection implements UISWTConfigSection {
 		final IntParameter tcplisten = new IntParameter(cMiniArea,
 				"TCP.Listen.Port", 1, 65535);
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		tcplisten.setLayoutData(gridData);
 
 		tcplisten.addChangeListener(new ParameterChangeAdapter() {
@@ -132,7 +131,6 @@ public class ConfigSectionConnection implements UISWTConfigSection {
 			final IntParameter udp_listen = new IntParameter(cMiniArea,
 					"UDP.Listen.Port", 1, 65535);
 			gridData = new GridData();
-			gridData.widthHint = 40;
 			udp_listen.setLayoutData(gridData);
 
 			final boolean MULTI_UDP = COConfigurationManager.ENABLE_MULTIPLE_UDP_PORTS && userMode > 1;
@@ -202,7 +200,6 @@ public class ConfigSectionConnection implements UISWTConfigSection {
 						});
 				
 				gridData = new GridData();
-				gridData.widthHint = 40;
 				non_data_udp_listen.setLayoutData( gridData );
 	
 				commonUDP.setAdditionalActionPerformer(new ChangeSelectionActionPerformer( non_data_udp_listen.getControls(), true ));
@@ -321,7 +318,6 @@ public class ConfigSectionConnection implements UISWTConfigSection {
 			IntParameter http_port = new IntParameter(http_group, "HTTP.Data.Listen.Port");
 
 			gridData = new GridData();
-			gridData.widthHint = 40;
 			http_port.setLayoutData( gridData );
 
 			label = new Label(http_group, SWT.NULL);
@@ -330,7 +326,6 @@ public class ConfigSectionConnection implements UISWTConfigSection {
 			IntParameter http_port_override = new IntParameter(http_group, "HTTP.Data.Listen.Port.Override");
 
 			gridData = new GridData();
-			gridData.widthHint = 40;
 			http_port_override.setLayoutData( gridData );
 
 			enable_http.setAdditionalActionPerformer( new ChangeSelectionActionPerformer( http_port ));
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java
index 487cb27..0b1ad25 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java
@@ -24,10 +24,8 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.*;
+
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.impl.ConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
@@ -38,7 +36,6 @@ import org.gudy.azureus2.platform.PlatformManagerFactory;
 import org.gudy.azureus2.plugins.platform.PlatformManagerException;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 import org.gudy.azureus2.ui.swt.Messages;
-import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.LinkLabel;
 import org.gudy.azureus2.ui.swt.config.*;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
@@ -130,7 +127,6 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
 		IntParameter max_connects = new IntParameter(gSocket,
 				"network.max.simultaneous.connect.attempts", 1, 100);    
 		gridData = new GridData();
-		gridData.widthHint = 30;
 		max_connects.setLayoutData(gridData);
 
 			// // max pending
@@ -143,7 +139,6 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
 		IntParameter max_pending_connects = new IntParameter(gSocket,
 				"network.tcp.max.connections.outstanding", 1, 65536 );    
 		gridData = new GridData();
-		gridData.widthHint = 30;
 		max_pending_connects.setLayoutData(gridData);
 		
 		
@@ -175,7 +170,6 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
 		final IntParameter port_bind = new IntParameter(gSocket,
 				"network.bind.local.port", 0, 65535);
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		port_bind.setLayoutData(gridData);
 		
 		
@@ -184,7 +178,6 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
 		final IntParameter mtu_size = new IntParameter(gSocket,"network.tcp.mtu.size");
 		mtu_size.setMaximumValue(512 * 1024);
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		mtu_size.setLayoutData(gridData);
 
 
@@ -192,7 +185,6 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
 		Messages.setLanguageText(lsend, CFG_PREFIX + "SO_SNDBUF");
 		final IntParameter SO_SNDBUF = new IntParameter(gSocket,	"network.tcp.socket.SO_SNDBUF");
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		SO_SNDBUF.setLayoutData(gridData);
 
 
@@ -200,7 +192,6 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
 		Messages.setLanguageText(lreceiv, CFG_PREFIX + "SO_RCVBUF");
 		final IntParameter SO_RCVBUF = new IntParameter(gSocket,	"network.tcp.socket.SO_RCVBUF");
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		SO_RCVBUF.setLayoutData(gridData);
 		
 
@@ -208,7 +199,7 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
 		Messages.setLanguageText(ltos, CFG_PREFIX + "IPDiffServ");
 		final StringParameter IPDiffServ = new StringParameter(gSocket,	"network.tcp.socket.IPDiffServ");
 		gridData = new GridData();
-		gridData.widthHint = 30;
+		gridData.widthHint = 100;
 		IPDiffServ.setLayoutData(gridData);
 
 
@@ -255,14 +246,12 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
 		Messages.setLanguageText(lreadsel, CFG_PREFIX + "read_select", new String[]{ String.valueOf( COConfigurationManager.getDefault("network.tcp.read.select.time"))});
 		final IntParameter read_select = new IntParameter(gSocket,	"network.tcp.read.select.time", 10, 250);
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		read_select.setLayoutData(gridData);
 		
 		Label lreadselmin = new Label(gSocket, SWT.NULL);
 		Messages.setLanguageText(lreadselmin, CFG_PREFIX + "read_select_min", new String[]{ String.valueOf( COConfigurationManager.getDefault("network.tcp.read.select.min.time"))});
 		final IntParameter read_select_min = new IntParameter(gSocket,	"network.tcp.read.select.min.time", 0, 100 );
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		read_select_min.setLayoutData(gridData);
 
 			// write select
@@ -271,14 +260,12 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
 		Messages.setLanguageText(lwritesel, CFG_PREFIX + "write_select", new String[]{ String.valueOf( COConfigurationManager.getDefault("network.tcp.write.select.time"))});
 		final IntParameter write_select = new IntParameter(gSocket,	"network.tcp.write.select.time", 10, 250);
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		write_select.setLayoutData(gridData);
 		
 		Label lwriteselmin = new Label(gSocket, SWT.NULL);
 		Messages.setLanguageText(lwriteselmin, CFG_PREFIX + "write_select_min", new String[]{ String.valueOf( COConfigurationManager.getDefault("network.tcp.write.select.min.time"))});
 		final IntParameter write_select_min = new IntParameter(gSocket,	"network.tcp.write.select.min.time", 0, 100 );
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		write_select_min.setLayoutData(gridData);
 
 		
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFile.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFile.java
index 4d88dfa..308f4c4 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFile.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFile.java
@@ -313,7 +313,6 @@ public class ConfigSectionFile implements UISWTConfigSection {
 
       IntParameter paramSaveInterval = new IntParameter(cResumeGroup, sCurConfigID);
       gridData = new GridData();
-      gridData.widthHint = 30;
       paramSaveInterval.setLayoutData(gridData);
 
       Label lblMinutes = new Label(cResumeGroup, SWT.NULL);
@@ -347,7 +346,6 @@ public class ConfigSectionFile implements UISWTConfigSection {
       Messages.setLanguageText(lblSavePeersMax, "ConfigView.section.file.save.peers.max");
       final IntParameter savePeersMax = new IntParameter(cResumeGroup, sCurConfigID);
       gridData = new GridData();
-      gridData.widthHint = 30;
       savePeersMax.setLayoutData(gridData);
       final Label lblPerTorrent = new Label(cResumeGroup, SWT.NULL);
       Messages.setLanguageText(lblPerTorrent, "ConfigView.section.file.save.peers.pertorrent");
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFilePerformance.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFilePerformance.java
index d5a7933..cddb3c8 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFilePerformance.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFilePerformance.java
@@ -69,7 +69,6 @@ public class ConfigSectionFilePerformance implements UISWTConfigSection {
     int userMode = COConfigurationManager.getIntParameter("User Mode");
 
     Composite cSection = new Composite(parent, SWT.NULL);
-  	cSection.addControlListener(new Utils.LabelWrapControlListener());
     layout = new GridLayout();
     layout.numColumns = 3;
     cSection.setLayout(layout);
@@ -126,7 +125,6 @@ public class ConfigSectionFilePerformance implements UISWTConfigSection {
 				"diskmanager.perf.cache.size", 1,
 				COConfigurationManager.CONFIG_CACHE_SIZE_MAX_MB);
     gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
-    gridData.widthHint = 30;
     cache_size.setLayoutData( gridData );
     
      
@@ -158,7 +156,6 @@ public class ConfigSectionFilePerformance implements UISWTConfigSection {
     IntParameter cache_not_smaller_than= new IntParameter(cSection, "diskmanager.perf.cache.notsmallerthan" );
     cache_not_smaller_than.setMinimumValue(0);
     gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
-    gridData.widthHint = 30;
     cache_not_smaller_than.setLayoutData( gridData );
     
     	
@@ -215,7 +212,6 @@ public class ConfigSectionFilePerformance implements UISWTConfigSection {
     Messages.setLanguageText(label, "ConfigView.section.file.max_open_files");
     IntParameter file_max_open = new IntParameter(cSection, "File Max Open");
     gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
-    gridData.widthHint = 30;
     file_max_open.setLayoutData( gridData );
     label = new Label(cSection, SWT.WRAP);
     gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
@@ -235,7 +231,6 @@ public class ConfigSectionFilePerformance implements UISWTConfigSection {
     label.setText(label_text);
     IntParameter write_block_limit = new IntParameter(cSection, "diskmanager.perf.write.maxmb" );
     gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
-    gridData.widthHint = 30;
     write_block_limit.setLayoutData( gridData );
     label = new Label(cSection, SWT.WRAP);
     gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
@@ -255,7 +250,6 @@ public class ConfigSectionFilePerformance implements UISWTConfigSection {
     label.setText(label_text);
     IntParameter check_piece_limit = new IntParameter(cSection, "diskmanager.perf.read.maxmb" );
     gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
-    gridData.widthHint = 30;
     check_piece_limit.setLayoutData( gridData );
     label = new Label(cSection, SWT.WRAP);
     gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionIPFilter.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionIPFilter.java
index cc45c3a..54c5849 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionIPFilter.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionIPFilter.java
@@ -237,7 +237,6 @@ public class ConfigSectionIPFilter implements UISWTConfigSection {
 
     FloatParameter discard_ratio = new FloatParameter(gBlockBanning, "Ip Filter Ban Discard Ratio");
     gridData = new GridData();
-    gridData.widthHint = 30;
     discard_ratio.setLayoutData(gridData);
 
 
@@ -264,7 +263,6 @@ public class ConfigSectionIPFilter implements UISWTConfigSection {
 
     IntParameter discard_min = new IntParameter(cIndent, "Ip Filter Ban Discard Min KB");
     gridData = new GridData();
-    gridData.widthHint = 30;
     discard_min.setLayoutData(gridData);
     
    	// block banning
@@ -274,9 +272,8 @@ public class ConfigSectionIPFilter implements UISWTConfigSection {
     "ConfigView.section.ipfilter.blockbanning");
 
     IntParameter block_banning = new IntParameter(gBlockBanning,
-    "Ip Filter Ban Block Limit");
+    "Ip Filter Ban Block Limit", 0, 256);
     gridData = new GridData();
-    gridData.widthHint = 30;
     block_banning.setLayoutData(gridData);
 
     // triggers
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterface.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterface.java
index e495232..63f86b5 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterface.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterface.java
@@ -25,8 +25,6 @@
 package org.gudy.azureus2.ui.swt.views.configsections;
 
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.*;
@@ -123,28 +121,28 @@ public class ConfigSectionInterface implements UISWTConfigSection {
 		
 		new BooleanParameter(cDisplay, "Remember transfer bar location", LBLKEY_PREFIX + "transferbar.remember_location");
 
-		if (!Constants.isOSX || SWT.getVersion() >= 3300) {
-
-	    Group gSysTray = new Group(cDisplay, SWT.NULL);
-	    Messages.setLanguageText(gSysTray, LBLKEY_PREFIX + "systray");
-	    layout = new GridLayout();
-	    gSysTray.setLayout(layout);
-	    gSysTray.setLayoutData(new GridData());
-
-			BooleanParameter est = new BooleanParameter(gSysTray,
-					"Enable System Tray", KEY_PREFIX + "enabletray");
-
-			BooleanParameter ctt = new BooleanParameter(gSysTray, "Close To Tray",
-					LBLKEY_PREFIX + "closetotray");
-			BooleanParameter mtt = new BooleanParameter(gSysTray, "Minimize To Tray",
-					LBLKEY_PREFIX + "minimizetotray");
-
-			est.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(ctt
-					.getControls()));
-			est.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(mtt
-					.getControls()));
-
-		}
+		Group gSysTray = new Group(cDisplay, SWT.NULL);
+		Messages.setLanguageText(gSysTray, LBLKEY_PREFIX + "systray");
+		layout = new GridLayout();
+		gSysTray.setLayout(layout);
+		gSysTray.setLayoutData(new GridData());
+
+		BooleanParameter est = new BooleanParameter(gSysTray, "Enable System Tray",
+				KEY_PREFIX + "enabletray");
+
+		BooleanParameter ctt = new BooleanParameter(gSysTray, "Close To Tray",
+				LBLKEY_PREFIX + "closetotray");
+		BooleanParameter mtt = new BooleanParameter(gSysTray, "Minimize To Tray",
+				LBLKEY_PREFIX + "minimizetotray");
+		BooleanParameter esttt = new BooleanParameter(gSysTray, "ui.systray.tooltip.enable",
+				"ConfigView.label.enableSystrayToolTip");
+
+		est.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
+				ctt.getControls()));
+		est.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
+				mtt.getControls()));
+		est.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
+				esttt.getControls()));
 		
         /**
          * Default download / upload limits available in the UI.
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceAlerts.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceAlerts.java
index 8d93d91..896a05f 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceAlerts.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceAlerts.java
@@ -420,7 +420,6 @@ public class ConfigSectionInterfaceAlerts implements UISWTConfigSection
 				"Message Popup Autoclose in Seconds", 0, 86400);
 		gridData = new GridData();
 		gridData.horizontalSpan = 1;
-		gridData.widthHint = 30;
 		auto_hide_alert.setLayoutData(gridData);
 		
 		// Use popup boxes rather than Mr Slidey.
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceDisplay.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceDisplay.java
index 67957a7..651f943 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceDisplay.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceDisplay.java
@@ -164,12 +164,6 @@ public class ConfigSectionInterfaceDisplay implements UISWTConfigSection {
 			});
 		}
 
-		if (Utils.isGTK) {
-			// See Eclipse Bug #42416 ([Platform Inconsistency] GC(Table) has wrong origin)
-			new BooleanParameter(cLook, "SWT_bGTKTableBug", MSG_PREFIX
-					+ "verticaloffset");
-		}
-
 		if (Constants.isOSX) {
 			new BooleanParameter(cLook, "enable_small_osx_fonts", MSG_PREFIX
 					+ "osx_small_fonts");
@@ -180,20 +174,19 @@ public class ConfigSectionInterfaceDisplay implements UISWTConfigSection {
   				+ "alternateTablePainting");
 		}
 
-		if (userMode > 0) {
-  		new BooleanParameter(cLook, "config.style.useSIUnits", MSG_PREFIX
-  				+ "useSIUnits");
-  		new BooleanParameter(cLook, "config.style.useUnitsRateBits",
-  				MSG_PREFIX + "useUnitsRateBits");
-  		new BooleanParameter(cLook, "config.style.doNotUseGB", MSG_PREFIX
-  				+ "doNotUseGB");
+	if (userMode > 0) {
+  		new BooleanParameter(cLook, "config.style.useSIUnits", MSG_PREFIX + "useSIUnits");
+  		
+  		new BooleanParameter(cLook, "config.style.forceSIValues", MSG_PREFIX + "forceSIValues");
+  		
+  		new BooleanParameter(cLook, "config.style.useUnitsRateBits", MSG_PREFIX + "useUnitsRateBits");
+  		
+  		new BooleanParameter(cLook, "config.style.doNotUseGB", MSG_PREFIX + "doNotUseGB");
   
-  		new BooleanParameter(cLook, "config.style.dataStatsOnly", MSG_PREFIX
-  				+ "dataStatsOnly");
+  		new BooleanParameter(cLook, "config.style.dataStatsOnly", MSG_PREFIX + "dataStatsOnly");
   
-  		new BooleanParameter(cLook, "config.style.separateProtDataStats", MSG_PREFIX
-  				+ "separateProtDataStats");
-		}
+  		new BooleanParameter(cLook, "config.style.separateProtDataStats", MSG_PREFIX + "separateProtDataStats");
+	}
 		
 		
     if( userMode > 1 ) {
@@ -223,21 +216,18 @@ public class ConfigSectionInterfaceDisplay implements UISWTConfigSection {
 		label = new Label(cArea, SWT.NULL);
 		Messages.setLanguageText(label, MSG_PREFIX + "inactiveUpdate");
 		gridData = new GridData();
-		gridData.widthHint = 15;
 		IntParameter inactiveUpdate = new IntParameter(cArea, "Refresh When Inactive", 1,	-1);
 		inactiveUpdate.setLayoutData(gridData);
 
 		label = new Label(cArea, SWT.NULL);
 		Messages.setLanguageText(label, MSG_PREFIX + "graphicsUpdate");
 		gridData = new GridData();
-		gridData.widthHint = 15;
 		IntParameter graphicUpdate = new IntParameter(cArea, "Graphics Update", 1,	-1);
 		graphicUpdate.setLayoutData(gridData);
 
 		label = new Label(cArea, SWT.NULL);
 		Messages.setLanguageText(label, MSG_PREFIX + "reOrderDelay");
 		gridData = new GridData();
-		gridData.widthHint = 15;
 		IntParameter reorderDelay = new IntParameter(cArea, "ReOrder Delay");
 		reorderDelay.setLayoutData(gridData);
 
@@ -274,6 +264,23 @@ public class ConfigSectionInterfaceDisplay implements UISWTConfigSection {
 			}
 		}
 		
+		if ( Constants.isOSX_10_5_OrHigher ){
+			
+			Composite cSWT = new Composite(cLook, SWT.NULL);
+			layout = new GridLayout();
+			layout.marginHeight = 0;
+			layout.marginWidth = 0;
+			layout.numColumns = 2;
+			cSWT.setLayout(layout);
+			cSWT.setLayoutData(new GridData());
+			
+			label = new Label(cSWT, SWT.NULL);
+			label.setText( "SWT Library" );
+			String[] swtLibraries = { "carbon", "cocoa" };
+					
+			new StringListParameter(cSWT, MSG_PREFIX + "swt.library.selection", swtLibraries, swtLibraries);
+		}
+		
 		return cLook;
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceStart.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceStart.java
index b0ce628..4506952 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceStart.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceStart.java
@@ -30,18 +30,12 @@ import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.UISwitcherUtil;
 import org.gudy.azureus2.ui.swt.config.BooleanParameter;
 import org.gudy.azureus2.ui.swt.config.ChangeSelectionActionPerformer;
 import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
-import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
-
-import com.aelitis.azureus.ui.UIFunctions;
-import com.aelitis.azureus.ui.UIFunctionsManager;
-
-import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 
 public class ConfigSectionInterfaceStart implements UISWTConfigSection {
   public String configSectionGetParentSection() {
@@ -99,11 +93,6 @@ public class ConfigSectionInterfaceStart implements UISWTConfigSection {
     new BooleanParameter(cStart, "Open Transfer Bar On Start", "ConfigView.label.open_transfer_bar_on_start");
     new BooleanParameter(cStart, "Start Minimized", "ConfigView.label.startminimized");
     
-    if (isAZ3) {
-			new BooleanParameter(cStart, "v3.Start Advanced",
-					"ConfigView.interface.start.library");
-		}
-  
 	// UI switcher window.
     Composite cUISwitcher = new Composite(cStart, SWT.NONE);
     layout = new GridLayout(2, false);
@@ -120,23 +109,7 @@ public class ConfigSectionInterfaceStart implements UISWTConfigSection {
 
 		ui_switcher_button.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
-				String uiOld = COConfigurationManager.getStringParameter("ui");
-				String uiNew = UISwitcherUtil.openSwitcherWindow(true);
-				if (!uiOld.equals(uiNew)) {
-  				int result = MessageBoxShell.open(parent.getShell(),
-  						MessageText.getString("dialog.uiswitcher.restart.title"),
-  						MessageText.getString("dialog.uiswitcher.restart.text"),
-  						new String[] {
-  							MessageText.getString("UpdateWindow.restart"),
-  							MessageText.getString("UpdateWindow.restartLater"),
-  						}, 0);
-  				if (result == 0) {
-  					UIFunctions uif = UIFunctionsManager.getUIFunctions();
-  					if (uif != null) {
-  						uif.dispose(true, false);
-  					}
-  				}
-				}
+				UISwitcherUtil.openSwitcherWindow();
 			}
 		});
     
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionPlugins.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionPlugins.java
index 760d3c6..9490a27 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionPlugins.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionPlugins.java
@@ -54,8 +54,12 @@ import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
+import org.gudy.azureus2.platform.PlatformManager;
+import org.gudy.azureus2.platform.PlatformManagerCapabilities;
+import org.gudy.azureus2.platform.PlatformManagerFactory;
 import org.gudy.azureus2.plugins.PluginException;
 import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.platform.PlatformManagerException;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 import org.gudy.azureus2.plugins.ui.config.Parameter;
 
@@ -314,9 +318,6 @@ public class ConfigSectionPlugins implements UISWTConfigSection, ParameterListen
 		infoGroup.setLayout(layout);
 
 		infoGroup.setLayout(new GridLayout());
-		if (SWT.getVersion() < 3105) { // screws up scrolling on 3.2M2
-			infoGroup.addControlListener(new Utils.LabelWrapControlListener());
-		}
 
 		String sep = System.getProperty("file.separator");
 
@@ -362,20 +363,17 @@ public class ConfigSectionPlugins implements UISWTConfigSection, ParameterListen
 
 		final String _sUserPluginDir = sUserPluginDir;
 
-		//TODO : Fix it for windows
 		label.addMouseListener(new MouseAdapter() {
 			public void mouseUp(MouseEvent arg0) {
 				if (_sUserPluginDir.endsWith("/plugins/")
 						|| _sUserPluginDir.endsWith("\\plugins\\")) {
 					File f = new File(_sUserPluginDir);
-					if (f.exists() && f.isDirectory()) {
-						Utils.launch(_sUserPluginDir);
-					} else {
-						String azureusDir = _sUserPluginDir.substring(0, _sUserPluginDir
+					String dir = _sUserPluginDir;
+					if (!(f.exists() && f.isDirectory())) {
+						dir = _sUserPluginDir.substring(0, _sUserPluginDir
 								.length() - 9);
-						System.out.println(azureusDir);
-						Utils.launch(azureusDir);
 					}
+					Utils.launch(dir);
 				}
 			}
 		});
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSecurity.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSecurity.java
index c254dbe..4fbf1ee 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSecurity.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSecurity.java
@@ -47,8 +47,10 @@ import org.gudy.azureus2.ui.swt.config.*;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
 import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
 import com.aelitis.azureus.core.security.*;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
@@ -320,6 +322,7 @@ ConfigSectionSecurity
 		    
 		    	// manage keys
 		    
+		    /*
 		    gridData = new GridData();
 		    gridData.horizontalSpan = 3;
 
@@ -384,11 +387,13 @@ ConfigSectionSecurity
 	    				
 	    				if ( error != null ){
 	    					
-			        		Utils.openMessageBox( 
-			        				manage_keys.getControl().getShell(),SWT.ICON_ERROR | SWT.OK,
-			        				MessageText.getString( "ConfigView.section.security.op.error.title" ),
-			        				MessageText.getString( "ConfigView.section.security.op.error", 
-			        						new String[]{ error }));
+	    					MessageBoxShell mb = new MessageBoxShell(
+	    							SWT.ICON_ERROR | SWT.OK,
+	    							MessageText.getString("ConfigView.section.security.op.error.title"),
+	    							MessageText.getString("ConfigView.section.security.op.error",
+	    									new String[] { error }));
+	      				mb.setParent(parent.getShell());
+	    					mb.open(null);
 	    				}
 	    				
 	    				boolean new_value = ecc_handler.getDefaultPasswordHandlerType() == CryptoManagerPasswordHandler.HANDLER_TYPE_SYSTEM;
@@ -399,6 +404,7 @@ ConfigSectionSecurity
 	    				}
 		    		}
 		    	});
+		    */
 		    
 	    		// reset keys
 		    
@@ -414,22 +420,33 @@ ConfigSectionSecurity
 				        public void 
 						handleEvent(Event event) 
 				        {
-				        	if ( Utils.openMessageBox(
-				        			parent.getShell(),SWT.ICON_WARNING | SWT.OK | SWT.CANCEL, SWT.CANCEL,
+				        	MessageBoxShell mb = new MessageBoxShell(
+				        			SWT.ICON_WARNING | SWT.OK | SWT.CANCEL,
 				        			MessageText.getString("ConfigView.section.security.resetkey.warning.title"),
-				        			MessageText.getString("ConfigView.section.security.resetkey.warning")) == SWT.OK ){ 
-		 									
-					        	try{
-					        		crypt_man.getECCHandler().resetKeys( "Manual key reset" );
-					        					        		
-					        	}catch( Throwable e ){
-				        		
-					        		Utils.openMessageBox( 
-					        			parent.getShell(),SWT.ICON_ERROR | SWT.OK,
-					        			MessageText.getString( "ConfigView.section.security.resetkey.error.title"),
-					        			getError( e ));
-					        	}
-		 					}
+				        			MessageText.getString("ConfigView.section.security.resetkey.warning"));
+				        	mb.setDefaultButtonUsingStyle(SWT.CANCEL);
+				        	mb.setParent(parent.getShell());
+
+				        	mb.open(new UserPrompterResultListener() {
+										public void prompterClosed(int returnVal) {
+											if (returnVal != SWT.OK) {
+												return;
+											}
+											
+											try{
+												crypt_man.getECCHandler().resetKeys( "Manual key reset" );
+												
+											}catch( Throwable e ){
+												
+												MessageBoxShell mb = new MessageBoxShell( 
+														SWT.ICON_ERROR | SWT.OK,
+														MessageText.getString( "ConfigView.section.security.resetkey.error.title"),
+														getError( e ));
+							  				mb.setParent(parent.getShell());
+							  				mb.open(null);
+											}
+										}
+									});
 				        }
 				    });
 		    
@@ -454,12 +471,14 @@ ConfigSectionSecurity
 				        		
 				        	}catch( Throwable e ){
 				        		
-			 					Utils.openMessageBox( 
-			 						parent.getShell(),
+			 					MessageBoxShell mb = new MessageBoxShell( 
 			 						SWT.ICON_ERROR | SWT.OK,
 			 						MessageText.getString( "ConfigView.section.security.resetkey.error.title" ),
 			 						getError( e ));
-				        	}
+			 					mb.setParent(parent.getShell());
+			 					mb.open(null);
+				        	};
+
 				        }
 				    });
 		    
@@ -496,11 +515,13 @@ ConfigSectionSecurity
 					        	
 					        	}catch( Throwable e ){
 					        	
-					        		Utils.openMessageBox( 
-					        				backup_keys_button.getShell(),SWT.ICON_ERROR | SWT.OK,
+					        		MessageBoxShell mb = new MessageBoxShell( 
+					        				SWT.ICON_ERROR | SWT.OK,
 					        				MessageText.getString( "ConfigView.section.security.op.error.title" ),
 					        				MessageText.getString( "ConfigView.section.security.op.error", 
 					        						new String[]{ getError(e) }));
+					    				mb.setParent(parent.getShell());
+					        		mb.open(null);
 					        	}
 				        	}
 				        }
@@ -549,10 +570,12 @@ ConfigSectionSecurity
 					  
 					        		if ( restart ){
 					        			
-						        		Utils.openMessageBox( 
-						        				backup_keys_button.getShell(),SWT.ICON_INFORMATION | SWT.OK,
+					        			MessageBoxShell mb = new MessageBoxShell( 
+						        				SWT.ICON_INFORMATION | SWT.OK,
 						        				MessageText.getString( "ConfigView.section.security.restart.title" ),
-						        				MessageText.getString( "ConfigView.section.security.restart.msg" )); 
+						        				MessageText.getString( "ConfigView.section.security.restart.msg" ));
+					      				mb.setParent(parent.getShell());
+					        			mb.open(null); 
 	
 						        		
 						        		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
@@ -564,11 +587,13 @@ ConfigSectionSecurity
 					        		}
 					        	}catch( Throwable e ){
 					        	
-					        		Utils.openMessageBox(  
-					        			backup_keys_button.getShell(),SWT.ICON_ERROR | SWT.OK,
+					        		MessageBoxShell mb = new MessageBoxShell(  
+					        			SWT.ICON_ERROR | SWT.OK,
 					        			MessageText.getString( "ConfigView.section.security.op.error.title" ),
 					        			MessageText.getString( "ConfigView.section.security.op.error", 
 					        					new String[]{ getError( e )}));
+					    				mb.setParent(parent.getShell());
+					        		mb.open(null);
 					        	}
 				        	}
 				        }
@@ -597,14 +622,14 @@ ConfigSectionSecurity
 			    final CryptoManager crypto_man 	= CryptoManagerFactory.getSingleton();
 				final CryptoHandler ecc_handler = crypto_man.getECCHandler();
 				
-				if ( ecc_handler.getDefaultPasswordHandlerType() == CryptoManagerPasswordHandler.HANDLER_TYPE_SYSTEM ){
-					
-					error = MessageText.getString( "ConfigView.section.security.nopw_v" );
-
-				}else{
+				//if ( ecc_handler.getDefaultPasswordHandlerType() == CryptoManagerPasswordHandler.HANDLER_TYPE_SYSTEM ){
+				//	
+				//	error = MessageText.getString( "ConfigView.section.security.nopw_v" );
+				//
+				//}else{
 					
 					error = MessageText.getString( "ConfigView.section.security.nopw" );
-				}
+				//}
 			}
 		}else{
 			
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSharing.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSharing.java
index 0f0ecc9..9896253 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSharing.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSharing.java
@@ -139,7 +139,6 @@ public class ConfigSectionSharing implements UISWTConfigSection {
 	period_label.setLayoutData( gridData );
 
     gridData = new GridData();
-    gridData.widthHint = 30;
 	IntParameter rescan_period = new IntParameter(gSharing, "Sharing Rescan Period");
     rescan_period.setMinimumValue(1);
     rescan_period.setLayoutData( gridData );
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java
index 5f77ef7..fce3910 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java
@@ -165,7 +165,7 @@ ConfigSectionTrackerClient
     
     StringParameter tcpOverride = new StringParameter(overrideGroup, "TCP.Listen.Port.Override");
     data = new GridData();
-    data.widthHint = 40;
+    data.widthHint = 50;
     tcpOverride.setLayoutData(data);
     
     tcpOverride.addChangeListener(new ParameterChangeAdapter() {
@@ -197,7 +197,6 @@ ConfigSectionTrackerClient
     
     IntParameter numwant = new IntParameter(overrideGroup, "Tracker Client Numwant Limit",0,100);
     data = new GridData();
-    data.widthHint = 40;
     numwant.setLayoutData(data);
     
     label = new Label(overrideGroup, SWT.WRAP);
@@ -206,7 +205,6 @@ ConfigSectionTrackerClient
     
     IntParameter minmininterval = new IntParameter(overrideGroup, "Tracker Client Min Announce Interval");
     data = new GridData();
-    data.widthHint = 40;
     minmininterval.setLayoutData(data);
 
     
@@ -219,7 +217,6 @@ ConfigSectionTrackerClient
     label = new Label(gMainTab, SWT.NULL);
     Messages.setLanguageText(label,  "ConfigView.section.tracker.client.connecttimeout");
     gridData = new GridData();
-    gridData.widthHint = 40;
     IntParameter	connect_timeout = new IntParameter(gMainTab, "Tracker Client Connect Timeout" );
     connect_timeout.setLayoutData(gridData);
     label = new Label(gMainTab, SWT.NULL);
@@ -229,7 +226,6 @@ ConfigSectionTrackerClient
     label = new Label(gMainTab, SWT.NULL);
     Messages.setLanguageText(label,  "ConfigView.section.tracker.client.readtimeout");
     gridData = new GridData();
-    gridData.widthHint = 40;
     IntParameter	read_timeout = new IntParameter(gMainTab, "Tracker Client Read Timeout" );
     read_timeout.setLayoutData(gridData);
     label = new Label(gMainTab, SWT.NULL);
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerServer.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerServer.java
index f417477..33fbf44 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerServer.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerServer.java
@@ -131,7 +131,7 @@ ConfigSectionTrackerServer
     final StringParameter tracker_ip = new StringParameter(gMainTab, "Tracker IP", "" );
 
     gridData = new GridData();
-    gridData.widthHint = 80;
+    gridData.widthHint = 120;
     tracker_ip.setLayoutData( gridData );
 
     Button check_button = new Button(gMainTab, SWT.PUSH);
@@ -168,10 +168,9 @@ ConfigSectionTrackerServer
         new BooleanParameter(gMainTab, "Tracker Port Enable", 
                              CFG_PREFIX + "tracker.port");
 
-    IntParameter tracker_port = new IntParameter(gMainTab, "Tracker Port");
+    IntParameter tracker_port = new IntParameter(gMainTab, "Tracker Port", 0, 65535);
 
     gridData = new GridData();
-    gridData.widthHint = 50;
     tracker_port.setLayoutData( gridData );
 
     final StringParameter tracker_port_backup = new StringParameter(gMainTab, "Tracker Port Backups", "" );
@@ -198,9 +197,8 @@ ConfigSectionTrackerServer
                              CFG_PREFIX + "tracker.sslport");
 
     IntParameter tracker_port_ssl = new IntParameter(gMainTab,
-					"Tracker Port SSL");
+					"Tracker Port SSL", 0, 65535);
     gridData = new GridData();
-    gridData.widthHint = 50;
     tracker_port_ssl.setLayoutData( gridData );
 
     final StringParameter tracker_port_ssl_backup = new StringParameter(gMainTab, "Tracker Port SSL Backups", "" );
@@ -433,7 +431,6 @@ ConfigSectionTrackerServer
     IntParameter pollIntervalMin = new IntParameter(gPollStuff, "Tracker Poll Interval Min");
 
     gridData = new GridData();
-    gridData.widthHint = 30;
     pollIntervalMin.setLayoutData( gridData );
 
     label = new Label(gPollStuff, SWT.NULL);
@@ -444,7 +441,6 @@ ConfigSectionTrackerServer
     IntParameter pollIntervalMax = new IntParameter(gPollStuff, "Tracker Poll Interval Max");
 
     gridData = new GridData();
-    gridData.widthHint = 30;
     pollIntervalMax.setLayoutData( gridData );
 
     // row
@@ -457,7 +453,6 @@ ConfigSectionTrackerServer
     IntParameter pollIntervalIncBy = new IntParameter(gPollStuff, "Tracker Poll Inc By");
 
     gridData = new GridData();
-    gridData.widthHint = 30;
     pollIntervalIncBy.setLayoutData( gridData );
 
     label = new Label(gPollStuff, SWT.NULL);
@@ -468,7 +463,6 @@ ConfigSectionTrackerServer
     IntParameter pollIntervalIncPer = new IntParameter(gPollStuff, "Tracker Poll Inc Per");
 
     gridData = new GridData();
-    gridData.widthHint = 30;
     pollIntervalIncPer.setLayoutData( gridData );
 
     
@@ -491,7 +485,6 @@ ConfigSectionTrackerServer
     IntParameter scrapeannouncepercentage = new IntParameter(gScrapeCache, "Tracker Scrape Retry Percentage");
 
     gridData = new GridData();
-    gridData.widthHint = 30;
     scrapeannouncepercentage.setLayoutData( gridData );
     
     label = new Label(gScrapeCache, SWT.NULL);
@@ -502,7 +495,6 @@ ConfigSectionTrackerServer
     IntParameter scrapeCachePeriod = new IntParameter(gScrapeCache, "Tracker Scrape Cache");
 
     gridData = new GridData();
-    gridData.widthHint = 30;
     scrapeCachePeriod.setLayoutData( gridData );
     
  
@@ -514,7 +506,6 @@ ConfigSectionTrackerServer
     IntParameter announceCacheMinPeers = new IntParameter(gScrapeCache, "Tracker Announce Cache Min Peers");
 
     gridData = new GridData();
-    gridData.widthHint = 30;
     announceCacheMinPeers.setLayoutData( gridData );
     
     label = new Label(gScrapeCache, SWT.NULL);
@@ -525,7 +516,6 @@ ConfigSectionTrackerServer
     IntParameter announceCachePeriod = new IntParameter(gScrapeCache, "Tracker Announce Cache");
 
     gridData = new GridData();
-    gridData.widthHint = 30;
     announceCachePeriod.setLayoutData( gridData );
 
     
@@ -540,7 +530,6 @@ ConfigSectionTrackerServer
     IntParameter maxPeersReturned = new IntParameter(gMainTab, "Tracker Max Peers Returned");
 
     gridData = new GridData();
-    gridData.widthHint = 50;
     maxPeersReturned.setLayoutData( gridData );
 
     label = new Label(gMainTab, SWT.NULL);
@@ -556,7 +545,6 @@ ConfigSectionTrackerServer
     IntParameter seedRetentionLimit = new IntParameter(gMainTab, "Tracker Max Seeds Retained");
 
     gridData = new GridData();
-    gridData.widthHint = 50;
     seedRetentionLimit.setLayoutData( gridData );
 
     label = new Label(gMainTab, SWT.NULL);
@@ -592,7 +580,6 @@ ConfigSectionTrackerServer
     IntParameter NATTimeout = new IntParameter(gNATDetails, "Tracker NAT Check Timeout");
 
     gridData = new GridData();
-    gridData.widthHint = 50;
     NATTimeout.setLayoutData( gridData );
 
  
@@ -620,7 +607,6 @@ ConfigSectionTrackerServer
     Label udp_version_label = new Label(gMainTab, SWT.NULL);
     Messages.setLanguageText(udp_version_label,  CFG_PREFIX + "tracker.udpversion");
     gridData = new GridData();
-    gridData.widthHint = 40;
     IntParameter	udp_version = new IntParameter(gMainTab, "Tracker Port UDP Version");
     udp_version.setLayoutData(gridData);
     label = new Label(gMainTab, SWT.NULL);
@@ -708,7 +694,6 @@ ConfigSectionTrackerServer
     IntParameter maxGetTime = new IntParameter(gProcessing, "Tracker Max GET Time");
  
     gridData = new GridData();
-    gridData.widthHint = 50;
     maxGetTime.setLayoutData( gridData );
 
     label = new Label(gProcessing, SWT.NULL);
@@ -724,7 +709,6 @@ ConfigSectionTrackerServer
     IntParameter maxPostTimeMultiplier = new IntParameter(gProcessing, "Tracker Max POST Time Multiplier");
 
     gridData = new GridData();
-    gridData.widthHint = 50;
     maxPostTimeMultiplier.setLayoutData( gridData );
 
     label = new Label(gProcessing, SWT.NULL);
@@ -741,7 +725,6 @@ ConfigSectionTrackerServer
     maxThreadsTime.setMinimumValue(1);
     maxThreadsTime.setMaximumValue(4096);
     gridData = new GridData();
-    gridData.widthHint = 50;
     maxThreadsTime.setLayoutData( gridData );
 
     label = new Label(gProcessing, SWT.NULL);
@@ -777,7 +760,6 @@ ConfigSectionTrackerServer
 
     IntParameter maxConcConn = new IntParameter(gNBTracker, "Tracker TCP NonBlocking Conc Max" );
     gridData = new GridData();
-    gridData.widthHint = 50;
     maxConcConn.setLayoutData( gridData );
 
     label = new Label(gNBTracker, SWT.NULL);
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransfer.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransfer.java
index 610367e..7075bfc 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransfer.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransfer.java
@@ -101,7 +101,6 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 		Messages.setLanguageText(label, "ConfigView.label.maxuploadspeed");
 
 		gridData = new GridData();
-		gridData.widthHint = 35;
 		final IntParameter paramMaxUploadSpeed = new IntParameter(cSection,
 				"Max Upload Speed KBs", 0, -1);
 		paramMaxUploadSpeed.setLayoutData(gridData);
@@ -134,7 +133,6 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 		enable_seeding_rate.setLayoutData(gridData);
 
 		gridData = new GridData();
-		gridData.widthHint = 35;
 		final IntParameter paramMaxUploadSpeedSeeding = new IntParameter(
 				cMaxUploadSpeedOptionsArea, "Max Upload Speed Seeding KBs", 0, -1);
 		paramMaxUploadSpeedSeeding.setLayoutData(gridData);
@@ -177,7 +175,6 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			Messages.setLanguageText(label, "ConfigView.label.maxuploadswhenbusymin" );
 
 			gridData = new GridData();
-			gridData.widthHint = 35;
 			new IntParameter(cSection, "max.uploads.when.busy.inc.min.secs", 0, -1).setLayoutData(gridData);
 		}
 		
@@ -188,7 +185,6 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 		Messages.setLanguageText(label, "ConfigView.label.maxdownloadspeed");
 		
 		gridData = new GridData();
-		gridData.widthHint = 35;
 		final IntParameter paramMaxDownSpeed = new IntParameter(cSection,
 				"Max Download Speed KBs", 0, -1);
 		paramMaxDownSpeed.setLayoutData(gridData);
@@ -318,7 +314,6 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			Messages.setLanguageText(label, "ConfigView.label.maxuploads");
 
 			gridData = new GridData();
-			gridData.widthHint = 35;
 			IntParameter paramMaxUploads = new IntParameter(cSection, "Max Uploads",
 					2, -1);
 			paramMaxUploads.setLayoutData(gridData);
@@ -348,7 +343,6 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			enable_seeding_uploads.setLayoutData(gridData);
 
 			gridData = new GridData();
-			gridData.widthHint = 35;
 			IntParameter paramMaxUploadsSeeding = new IntParameter(
 					cMaxUploadsOptionsArea, "Max Uploads Seeding", 2, -1);
 			paramMaxUploadsSeeding.setLayoutData(gridData);
@@ -365,7 +359,6 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			Messages.setLanguageText(label, "ConfigView.label.max_peers_per_torrent");
 
 			gridData = new GridData();
-			gridData.widthHint = 35;
 			IntParameter paramMaxClients = new IntParameter(cSection,
 					"Max.Peer.Connections.Per.Torrent");
 			paramMaxClients.setLayoutData(gridData);
@@ -398,7 +391,6 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			enable_max_peers_seeding.setLayoutData(gridData);
 
 			gridData = new GridData();
-			gridData.widthHint = 35;
 			IntParameter paramMaxPeersSeeding = new IntParameter(
 					cMaxPeersOptionsArea, "Max.Peer.Connections.Per.Torrent.When.Seeding", 0, -1);
 			paramMaxPeersSeeding.setLayoutData(gridData);
@@ -415,7 +407,6 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			Messages.setLanguageText(label, "ConfigView.label.max_peers_total");
 
 			gridData = new GridData();
-			gridData.widthHint = 35;
 			IntParameter paramMaxClientsTotal = new IntParameter(cSection,
 					"Max.Peer.Connections.Total");
 			paramMaxClientsTotal.setLayoutData(gridData);
@@ -426,7 +417,6 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			Messages.setLanguageText(label, "ConfigView.label.maxseedspertorrent");
 
 			gridData = new GridData();
-			gridData.widthHint = 35;
 			new IntParameter(cSection,"Max Seeds Per Torrent").setLayoutData(gridData);
 
 			
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferLAN.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferLAN.java
index eb084b5..4669e99 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferLAN.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferLAN.java
@@ -111,7 +111,6 @@ public class ConfigSectionTransferLAN implements UISWTConfigSection {
 		
 		IntParameter lan_max_upload = new IntParameter( cSection, "Max LAN Upload Speed KBs" );
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		lan_max_upload.setLayoutData(gridData);
 		Label llmux = new Label(cSection, SWT.NULL);
 		Messages.setLanguageText( llmux, CFG_PREFIX + "uploadrate" );
@@ -119,7 +118,6 @@ public class ConfigSectionTransferLAN implements UISWTConfigSection {
 		
 		IntParameter lan_max_download = new IntParameter( cSection, "Max LAN Download Speed KBs" );
 		gridData = new GridData();
-		gridData.widthHint = 40;
 		lan_max_download.setLayoutData(gridData);
 		Label llmdx = new Label(cSection, SWT.NULL);
 		Messages.setLanguageText( llmdx, CFG_PREFIX + "downloadrate" );
diff --git a/org/gudy/azureus2/ui/swt/views/file/FileInfoView.java b/org/gudy/azureus2/ui/swt/views/file/FileInfoView.java
index e86c2c4..43d6411 100644
--- a/org/gudy/azureus2/ui/swt/views/file/FileInfoView.java
+++ b/org/gudy/azureus2/ui/swt/views/file/FileInfoView.java
@@ -46,14 +46,18 @@ import org.gudy.azureus2.core3.peer.PEPiece;
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Debug;
 
+import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.Legend;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.ui.swt.views.IViewExtension;
 
 
 
-public class FileInfoView extends AbstractIView {
+public class FileInfoView
+	extends AbstractIView
+	implements IViewExtension
+{
 	private final static int BLOCK_FILLSIZE = 14;
 
 	private final static int BLOCK_SPACING = 2;
@@ -88,6 +92,9 @@ public class FileInfoView extends AbstractIView {
 
 	Image img = null;
 
+	// accessed only in SWT Thread
+	private boolean refreshInfoCanvasQueued;
+
 	/**
 	 * Initialize
 	 *
@@ -220,25 +227,16 @@ public class FileInfoView extends AbstractIView {
 			
 			public void handleEvent(Event e) {
 				
+				if (refreshInfoCanvasQueued) {
+					return;
+				}
+				
+				refreshInfoCanvasQueued = true;
+
 					// wrap in asyncexec because sc.setMinWidth (called later) doesn't work
 					// too well inside a resize (the canvas won't size isn't always updated)
 
-				SWTThread.getInstance().limitFrequencyAsyncExec(
-					this,
-					e.widget.getDisplay(),
-					new AERunnable() {
-						public void runSupport() {
-							if (img != null) {
-								int iOldColCount = img.getBounds().width / BLOCK_SIZE;
-								int iNewColCount = fileInfoCanvas.getClientArea().width / BLOCK_SIZE;
-								if (iOldColCount != iNewColCount)
-									refreshInfoCanvas();
-							}
-						}
-					});
-			
-				/*
-				e.widget.getDisplay().asyncExec(new AERunnable() {
+				Utils.execSWTThreadLater(0, new AERunnable() {
 					public void runSupport() {
 						if (img != null) {
 							int iOldColCount = img.getBounds().width / BLOCK_SIZE;
@@ -248,7 +246,6 @@ public class FileInfoView extends AbstractIView {
 						}
 					}
 				});
-				*/
 			}
 		});
 
@@ -362,6 +359,7 @@ public class FileInfoView extends AbstractIView {
 	}
 	
 	protected void refreshInfoCanvas() {
+		refreshInfoCanvasQueued = false;
 		Rectangle bounds = fileInfoCanvas.getClientArea();
 		if (bounds.width <= 0 || bounds.height <= 0)
 			return;
@@ -478,8 +476,17 @@ public class FileInfoView extends AbstractIView {
 			font = null;
 		}
 		
-		SWTThread.getInstance().removeLimitedFrequencyOwner(this);
-
 		super.delete();
 	}
+
+	public Menu getPrivateMenu() {
+		return null;
+	}
+
+	public void viewActivated() {
+		refreshInfoCanvas();
+	}
+
+	public void viewDeactivated() {
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/peer/PeerInfoView.java b/org/gudy/azureus2/ui/swt/views/peer/PeerInfoView.java
index 1fc80b9..77e77ab 100644
--- a/org/gudy/azureus2/ui/swt/views/peer/PeerInfoView.java
+++ b/org/gudy/azureus2/ui/swt/views/peer/PeerInfoView.java
@@ -49,11 +49,13 @@ import org.gudy.azureus2.core3.util.DisplayFormatters;
 import org.gudy.azureus2.plugins.Plugin;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.Legend;
 import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
 import org.gudy.azureus2.ui.swt.debug.UIDebugGenerator;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.ui.swt.views.IViewExtension;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
@@ -69,7 +71,10 @@ import com.aelitis.azureus.core.peermanager.piecepicker.util.BitFlags;
  * 
  * @todo on paint, paint cached image instead of recalc
  */
-public class PeerInfoView extends AbstractIView implements ObfusticateImage {
+public class PeerInfoView
+	extends AbstractIView
+	implements ObfusticateImage, IViewExtension
+{
 	private final static int BLOCK_FILLSIZE = 14;
 
 	private final static int BLOCK_SPACING = 2;
@@ -118,6 +123,8 @@ public class PeerInfoView extends AbstractIView implements ObfusticateImage {
 
 	Image img = null;
 
+	protected boolean refreshInfoCanvasQueued;
+
 	/**
 	 * Initialize
 	 *
@@ -272,10 +279,19 @@ public class PeerInfoView extends AbstractIView implements ObfusticateImage {
 
 		peerInfoCanvas.addListener(SWT.Resize, new Listener() {
 			public void handleEvent(Event e) {
+				if (refreshInfoCanvasQueued || !peerInfoCanvas.isVisible()) {
+					return;
+				}
+				
 				// wrap in asyncexec because sc.setMinWidth (called later) doesn't work
 				// too well inside a resize (the canvas won't size isn't always updated)
-				e.widget.getDisplay().asyncExec(new AERunnable() {
+				Utils.execSWTThreadLater(100, new AERunnable() {
 					public void runSupport() {
+						if (refreshInfoCanvasQueued) {
+							return;
+						}
+						refreshInfoCanvasQueued = true;
+
 						if (img != null) {
 							int iOldColCount = img.getBounds().width / BLOCK_SIZE;
 							int iNewColCount = peerInfoCanvas.getClientArea().width / BLOCK_SIZE;
@@ -369,7 +385,9 @@ public class PeerInfoView extends AbstractIView implements ObfusticateImage {
 		}
 	}
 
-	protected void refreshInfoCanvas() {
+	private void refreshInfoCanvas() {
+		refreshInfoCanvasQueued = false;
+
 		peerInfoCanvas.layout(true);
 		Rectangle bounds = peerInfoCanvas.getClientArea();
 		if (bounds.width <= 0 || bounds.height <= 0)
@@ -601,4 +619,15 @@ public class PeerInfoView extends AbstractIView implements ObfusticateImage {
 		UIDebugGenerator.obfusticateArea(image, topLabel, shellOffset, "");
 		return image;
 	}
+
+	public Menu getPrivateMenu() {
+		return null;
+	}
+
+	public void viewActivated() {
+		refreshInfoCanvas();
+	}
+
+	public void viewDeactivated() {
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/piece/PieceInfoView.java b/org/gudy/azureus2/ui/swt/views/piece/PieceInfoView.java
index 1945875..1659d59 100644
--- a/org/gudy/azureus2/ui/swt/views/piece/PieceInfoView.java
+++ b/org/gudy/azureus2/ui/swt/views/piece/PieceInfoView.java
@@ -469,7 +469,7 @@ public class PieceInfoView
 				}
 
 				if (oldBlockInfo != null && i < oldBlockInfo.length
-						&& oldBlockInfo[i].equals(newBlockInfo[i])) {
+						&& oldBlockInfo[i].sameAs(newBlockInfo[i])) {
 					iCol++;
 					continue;
 				}
@@ -654,9 +654,7 @@ public class PieceInfoView
 			haveWidth = -1;
 		}
 		
-		// @see java.lang.Object#equals(java.lang.Object)
-		public boolean equals(Object obj) {
-			BlockInfo otherBlockInfo = (BlockInfo) obj;
+		public boolean sameAs(BlockInfo otherBlockInfo) {
 			return haveWidth == otherBlockInfo.haveWidth
 					&& availNum == otherBlockInfo.availNum
 					&& availDotted == otherBlockInfo.availDotted
diff --git a/org/gudy/azureus2/ui/swt/views/stats/DHTView.java b/org/gudy/azureus2/ui/swt/views/stats/DHTView.java
index 55181ea..8162907 100644
--- a/org/gudy/azureus2/ui/swt/views/stats/DHTView.java
+++ b/org/gudy/azureus2/ui/swt/views/stats/DHTView.java
@@ -687,9 +687,11 @@ public class DHTView extends AbstractIView {
       lblFindValues[i].setText("" + findValues[i]);
     }
     
-    long[] stores = transportStats.getStores();
+    long[] stores 	= transportStats.getStores();
+    long[] qstores 	= transportStats.getQueryStores();
+    
     for(int i = 0 ; i < 4 ; i++) {
-      lblStores[i].setText("" + stores[i]);
+      lblStores[i].setText("" + stores[i] + " (" + qstores[i] + ")");
     }
     long[] data = transportStats.getData();
     for(int i = 0 ; i < 4 ; i++) {
diff --git a/org/gudy/azureus2/ui/swt/views/stats/TrackerStatsView.java b/org/gudy/azureus2/ui/swt/views/stats/TrackerStatsView.java
new file mode 100644
index 0000000..531d81b
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/stats/TrackerStatsView.java
@@ -0,0 +1,44 @@
+package org.gudy.azureus2.ui.swt.views.stats;
+
+import java.util.List;
+
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerFactory;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerFactoryListener;
+import org.gudy.azureus2.ui.swt.views.AbstractIView;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+
+public class TrackerStatsView
+	extends AbstractIView
+{
+	private AzureusCore core;
+
+	public TrackerStatsView() {
+  	AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+			public void azureusCoreRunning(AzureusCore core) {
+				init(core);
+			}
+		});
+	}
+
+	protected void init(AzureusCore core) {
+		this.core = core;
+		
+		TRTrackerAnnouncerFactory.addListener(new TRTrackerAnnouncerFactoryListener() {
+			public void clientDestroyed(TRTrackerAnnouncer client) {
+				System.out.println("ADD " + client.getTrackerUrl().toString());
+			}
+			
+			public void clientCreated(TRTrackerAnnouncer client) {
+			}
+		});
+		List dms = core.getGlobalManager().getDownloadManagers();
+		for (Object oDM : dms) {
+			DownloadManager dm = (DownloadManager) oDM;
+		}
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/stats/TransferStatsView.java b/org/gudy/azureus2/ui/swt/views/stats/TransferStatsView.java
index 1a55668..98fae7f 100644
--- a/org/gudy/azureus2/ui/swt/views/stats/TransferStatsView.java
+++ b/org/gudy/azureus2/ui/swt/views/stats/TransferStatsView.java
@@ -374,20 +374,26 @@ public class TransferStatsView extends AbstractIView {
   }
   
   public void delete() {
-	Utils.disposeComposite(generalPanel);
-	Utils.disposeComposite(blahPanel);
-    pingGraph.dispose();
- 
-    for (int i=0;i<plot_views.length;i++){
+		Utils.disposeComposite(generalPanel);
+		Utils.disposeComposite(blahPanel);
+		if (pingGraph != null) {
+			pingGraph.dispose();
+		}
 
-    	plot_views[i].dispose();
-    }
+		if (plot_views != null) {
+			for (int i = 0; i < plot_views.length; i++) {
 
-    for (int i=0;i<zone_views.length;i++){
+				plot_views[i].dispose();
+			}
+		}
 
-    	zone_views[i].dispose();
-    }
-  }
+		if (zone_views != null) {
+			for (int i = 0; i < zone_views.length; i++) {
+
+				zone_views[i].dispose();
+			}
+		}
+	}
 
   public String getFullTitle() {
     return MessageText.getString("SpeedView.title.full"); //$NON-NLS-1$
diff --git a/org/gudy/azureus2/ui/swt/views/table/TableViewFilterCheck.java b/org/gudy/azureus2/ui/swt/views/table/TableViewFilterCheck.java
new file mode 100644
index 0000000..fc1931f
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/TableViewFilterCheck.java
@@ -0,0 +1,32 @@
+/**
+ * Created on Oct 4, 2009
+ *
+ * Copyright 2008 Vuze, Inc.  All rights reserved.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License only.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA 
+ */
+ 
+package org.gudy.azureus2.ui.swt.views.table;
+
+
+/**
+ * @author TuxPaper
+ * @created Oct 4, 2009
+ *
+ */
+public interface TableViewFilterCheck<DATASOURCETYPE>
+{
+	public boolean filterCheck(DATASOURCETYPE ds, String filter, boolean regex);
+	
+	public void filterSet(String filter);
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/TableViewSWT.java b/org/gudy/azureus2/ui/swt/views/table/TableViewSWT.java
index 2284d6a..199c13e 100644
--- a/org/gudy/azureus2/ui/swt/views/table/TableViewSWT.java
+++ b/org/gudy/azureus2/ui/swt/views/table/TableViewSWT.java
@@ -27,6 +27,7 @@ import org.eclipse.swt.events.KeyListener;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
 
 import org.gudy.azureus2.ui.swt.views.IView;
 
@@ -133,4 +134,36 @@ public interface TableViewSWT<DATASOURCETYPE>
 	 * @since 3.1.1.1
 	 */
 	void addRefreshListener(TableRowRefreshListener listener);
+
+	/**
+	 * @return
+	 *
+	 * @since 4.1.0.9
+	 */
+	String getFilterText();
+
+	/**
+	 * @param filterCheck
+	 *
+	 * @since 4.1.0.9
+	 */
+	void enableFilterCheck(Text txtFilter, TableViewFilterCheck<DATASOURCETYPE> filterCheck);
+
+	/**
+	 * @param s
+	 *
+	 * @since 4.1.0.8
+	 */
+	void setFilterText(String s);
+
+	/**
+	 * @param composite
+	 * @param min
+	 * @param max
+	 * 
+	 * @since 4.1.0.9
+	 */
+	boolean enableSizeSlider(Composite composite, int min, int max);
+
+	void disableSizeSlider();
 }
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableCellImpl.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableCellImpl.java
index d3e5c3b..899a290 100644
--- a/org/gudy/azureus2/ui/swt/views/table/impl/TableCellImpl.java
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableCellImpl.java
@@ -26,33 +26,44 @@
 package org.gudy.azureus2.ui.swt.views.table.impl;
 
 import java.text.Collator;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Locale;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.*;
-
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.logging.LogEvent;
 import org.gudy.azureus2.core3.logging.LogIDs;
 import org.gudy.azureus2.core3.logging.Logger;
-import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.core3.util.AEMonitor;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.SystemTime;
+import org.gudy.azureus2.plugins.ui.Graphic;
+import org.gudy.azureus2.plugins.ui.UIRuntimeException;
+import org.gudy.azureus2.plugins.ui.SWT.GraphicSWT;
+import org.gudy.azureus2.plugins.ui.tables.*;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.*;
 import org.gudy.azureus2.ui.swt.debug.ObfusticateCellText;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.plugins.UISWTGraphic;
 import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
-import org.gudy.azureus2.ui.swt.views.table.*;
+import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
+import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
+import org.gudy.azureus2.ui.swt.views.table.TableRowSWT;
+import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnSWTUtils;
 
-import com.aelitis.azureus.ui.common.table.*;
-
-import org.gudy.azureus2.plugins.ui.Graphic;
-import org.gudy.azureus2.plugins.ui.UIRuntimeException;
-import org.gudy.azureus2.plugins.ui.SWT.GraphicSWT;
-import org.gudy.azureus2.plugins.ui.tables.*;
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.common.table.TableColumnSortObject;
+import com.aelitis.azureus.ui.common.table.TableRowCore;
+import com.aelitis.azureus.ui.common.table.TableView;
 
 
 /** TableCellImpl represents one cell in the table.  
@@ -494,7 +505,7 @@ public class TableCellImpl
 				&& ((Long) sortValue).longValue() == valueToSort)
 			return false;
 
-		return _setSortValue(new Long(valueToSort));
+		return _setSortValue(Long.valueOf(valueToSort));
   }
   
   public boolean setSortValue( float valueToSort ) {
@@ -1144,7 +1155,7 @@ public class TableCellImpl
 			  if (bDebug)
 				  debug("invoke refresh; wasValid? " + bWasValid);
 
-			  long lTimeStart = SystemTime.getMonotonousTime();
+			  long lTimeStart = Constants.isCVSVersion()?SystemTime.getMonotonousTime():0;
 			  tableColumn.invokeCellRefreshListeners(this, !bCellVisible);
 			  if (refreshListeners != null) {
 				  for (int i = 0; i < refreshListeners.size(); i++) {
@@ -1155,9 +1166,11 @@ public class TableCellImpl
 						  l.refresh(this);
 				  }
 			  }
-			  long lTimeEnd = SystemTime.getMonotonousTime();
-			  tableColumn.addRefreshTime(lTimeEnd - lTimeStart);
-
+			  if ( Constants.isCVSVersion()){
+				  long lTimeEnd = SystemTime.getMonotonousTime();
+				  tableColumn.addRefreshTime(lTimeEnd - lTimeStart);
+			  }
+			  
 			  // Change to valid only if we weren't valid before the listener calls
 			  // This is in case the listeners set valid to false when it was true
 			  if (!bWasValid && !hasFlag(FLAG_MUSTREFRESH)) {
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWTImpl.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWTImpl.java
index c85d3b7..daf0874 100644
--- a/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWTImpl.java
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWTImpl.java
@@ -21,8 +21,12 @@
  */
 package org.gudy.azureus2.ui.swt.views.table.impl;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.*;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.*;
@@ -39,11 +43,8 @@ import org.gudy.azureus2.core3.logging.LogEvent;
 import org.gudy.azureus2.core3.logging.LogIDs;
 import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.core3.util.Timer;
 import org.gudy.azureus2.ui.common.util.MenuItemManager;
-import org.gudy.azureus2.ui.swt.MenuBuildUtils;
-import org.gudy.azureus2.ui.swt.Messages;
-import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.*;
 import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
 import org.gudy.azureus2.ui.swt.debug.UIDebugGenerator;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
@@ -52,17 +53,18 @@ import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
 import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
 import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
 import org.gudy.azureus2.ui.swt.views.IView;
+import org.gudy.azureus2.ui.swt.views.IViewExtension;
 import org.gudy.azureus2.ui.swt.views.columnsetup.TableColumnSetupWindow;
 import org.gudy.azureus2.ui.swt.views.table.*;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnSWTUtils;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableContextMenuManager;
-import org.gudy.azureus2.ui.swt.views.utils.VerticalAligner;
 
 import com.aelitis.azureus.ui.common.table.*;
 import com.aelitis.azureus.ui.common.table.impl.TableViewImpl;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
 
 import org.gudy.azureus2.plugins.ui.tables.TableCellMouseEvent;
 import org.gudy.azureus2.plugins.ui.tables.TableContextMenuItem;
@@ -102,8 +104,8 @@ import org.gudy.azureus2.pluginsimpl.local.ui.tables.TableContextMenuItemImpl;
 public class TableViewSWTImpl<DATASOURCETYPE>
 	extends TableViewImpl<DATASOURCETYPE>
 	implements ParameterListener, TableViewSWT<DATASOURCETYPE>,
-	TableStructureModificationListener<DATASOURCETYPE>, ObfusticateImage
-
+	TableStructureModificationListener<DATASOURCETYPE>, ObfusticateImage,
+	KeyListener
 {
 	private final static LogIDs LOGID = LogIDs.GUI;
 
@@ -112,9 +114,6 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	// Virtual tables don't flicker when updating a cell (Windows)
 	private final static boolean DISABLEVIRTUAL = SWT.getVersion() < 3138;
 
-	private final static boolean COLUMN_CLICK_DELAY = Constants.isOSX
-			&& SWT.getVersion() >= 3221 && SWT.getVersion() <= 3222;
-
 	private static final boolean DEBUG_SORTER = false;
 
 	// Shorter name for ConfigManager, easier to read code
@@ -128,6 +127,15 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	private static final boolean TRIGGER_PAINT_ON_SELECTIONS = false;
 
+	private static final int ASYOUTYPE_MODE_FIND = 0;
+	private static final int ASYOUTYPE_MODE_FILTER = 1;
+	private static final int ASYOUTYPE_MODE = ASYOUTYPE_MODE_FILTER;
+	private static final int ASYOUTYPE_UPDATEDELAY = 300;
+
+	private static final Color COLOR_FILTER_REGEX	= Colors.fadedYellow;
+	
+	private static final boolean DEBUG_CELL_CHANGES = false;
+
 	/** TableID (from {@link org.gudy.azureus2.plugins.ui.tables.TableManager}) 
 	 * of the table this class is
 	 * handling.  Config settings are stored with the prefix of 
@@ -183,6 +191,10 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	 */
 	private Map<DATASOURCETYPE, TableRowCore> mapDataSourceToRow;
 
+	private AEMonitor listUnfilteredDatasources_mon = new AEMonitor("TableView:uds");
+
+	private Set<DATASOURCETYPE> listUnfilteredDataSources;
+
 	private AEMonitor dataSourceToRow_mon = new AEMonitor("TableView:OTSI");
 
 	private List<TableRowSWT> sortedRows;
@@ -197,9 +209,6 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	/** TimeStamp of when last sorted all the rows was */
 	private long lLastSortedOn;
 
-	/* position of mouse in table.  Used for context menu. */
-	private int iMouseX = -1;
-
 	/** For updating GUI.  
 	 * Some UI objects get updating every X cycles (user configurable) 
 	 */
@@ -211,11 +220,6 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	protected int reOrderDelay = configMan.getIntParameter("ReOrder Delay");
 
-	/** Check Column Widths every 10 seconds on Pre 3.0RC1 on OSX if view is active.  
-	 * Other OSes can capture column width changes automatically */
-	private int checkColumnWidthsEvery = (Constants.isOSX && SWT.getVersion() < 3054)
-			? 10000 / configMan.getIntParameter("GUI Refresh") : 0;
-
 	/**
 	 * Cache of selected table items to bypass insufficient drawing on Mac OS X
 	 */
@@ -254,9 +258,6 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	private long lCancelSelectionTriggeredOn = -1;
 
-	// XXX Remove after column selection is no longered triggered on column resize (OSX)
-	private long lLastColumnResizeOn = -1;
-
 	private List<TableViewSWTMenuFillListener> listenersMenuFill = new ArrayList<TableViewSWTMenuFillListener>(
 			1);
 
@@ -285,6 +286,9 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	private boolean headerVisible = true;
 
+	/**
+	 * Up to date list of selected rows, so we can access rows without being on SWT Thread
+	 */
 	private int[] selectedRowIndexes;
 
 	private List<DATASOURCETYPE> listSelectedCoreDataSources;
@@ -302,6 +306,29 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	// private Rectangle firstClientArea;
 
 	private int lastHorizontalPos;
+	
+
+	// class used to keep filter stuff in a nice readable parcel
+	class filter {
+		Text widget = null;
+		
+		TimerEvent eventUpdate;
+		
+		String text = "";
+		
+		long lastFilterTime;
+		
+		boolean regex = false;
+		
+		TableViewFilterCheck<DATASOURCETYPE> checker;
+		
+		String nextText = "";
+		
+		ModifyListener widgetModifyListener;
+	};
+	
+	filter filter;
+	
 
 	/**
 	 * Main Initializer
@@ -331,6 +358,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 		mapDataSourceToRow = new LightHashMap<DATASOURCETYPE, TableRowCore>();
 		sortedRows = new ArrayList<TableRowSWT>();
+		listUnfilteredDataSources = new HashSet<DATASOURCETYPE>();
 	}
 
 	/**
@@ -586,6 +614,13 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				try {
 					((CTabItem) e.item).getControl().setVisible(true);
 					((CTabItem) e.item).getControl().moveAbove(null);
+
+					// TODO: Need to viewDeactivated old one
+					IView view = getActiveSubView();
+					if (view instanceof IViewExtension) {
+						((IViewExtension)view).viewActivated();
+					}
+					
 				} catch (Exception t) {
 				}
 			}
@@ -711,65 +746,29 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		// Setup table
 		// -----------
 
-		// XXX On linux (an other OSes?), changing the column indicator doesn't 
-		//     work until the table is shown.  Since SWT.Show doesn't trigger,
-		//     use the first paint trigger.
-		if (!Utils.SWT32_TABLEPAINT) {
-			table.addPaintListener(new PaintListener() {
-				boolean first = true;
-
-				public void paintControl(PaintEvent event) {
-					if (first) {
-						changeColumnIndicator();
-						// This fixes the scrollbar not being long enough on Win2k
-						// There may be other methods to get it to refresh right, but
-						// layout(true, true) didn't work.
-						table.setRedraw(false);
-						table.setRedraw(true);
-						first = false;
-					}
-					if (event.width == 0 || event.height == 0) {
-						return;
-					}
-					visibleRowsChanged();
-					doPaint(event.gc, new Rectangle(event.x, event.y, event.width,
-							event.height));
-				}
-			});
-		}
-
-		if (Utils.SWT32_TABLEPAINT) {
-			table.addPaintListener(new PaintListener() {
-				public void paintControl(PaintEvent event) {
-					changeColumnIndicator();
-					// This fixes the scrollbar not being long enough on Win2k
-					// There may be other methods to get it to refresh right, but
-					// layout(true, true) didn't work.
-					table.setRedraw(false);
-					table.setRedraw(true);
-					table.removePaintListener(this);
-				}
-			});
-
-			// SWT 3.2 only.  Code Ok -- Only called in SWT 3.2 mode
-			table.addListener(SWT.PaintItem, new Listener() {
-				public void handleEvent(Event event) {
-					//visibleRowsChanged();
-					paintItem(event);
-				}
-			});
-			//table.addListener(SWT.Paint, new Listener() {
-			//	public void handleEvent(Event event) {
-			//		System.out.println("paint " + event.getBounds() + ";" + table.getColumnCount());
-			//	}
-			//});
-		}
+		table.addPaintListener(new PaintListener() {
+			public void paintControl(PaintEvent event) {
+				changeColumnIndicator();
+				// This fixes the scrollbar not being long enough on Win2k
+				// There may be other methods to get it to refresh right, but
+				// layout(true, true) didn't work.
+				table.setRedraw(false);
+				table.setRedraw(true);
+				table.removePaintListener(this);
+			}
+		});
 
-		table.addListener(SWT.Activate, new Listener() {
+		table.addListener(SWT.PaintItem, new Listener() {
 			public void handleEvent(Event event) {
-				refreshVisibleRows();
+				//visibleRowsChanged();
+				paintItem(event);
 			}
 		});
+		//table.addListener(SWT.Paint, new Listener() {
+		//	public void handleEvent(Event event) {
+		//		System.out.println("paint " + event.getBounds() + ";" + table.getColumnCount());
+		//	}
+		//});
 
 		ScrollBar horizontalBar = table.getHorizontalBar();
 		if (horizontalBar != null) {
@@ -800,9 +799,11 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 					event.width = preferredWidth;
 				}
 
-				int defaultHeight = getRowDefaultHeight();
-				if (event.height < defaultHeight) {
-					event.height = defaultHeight;
+				if (slider == null) {
+  				int defaultHeight = getRowDefaultHeight();
+  				if (event.height < defaultHeight) {
+  					event.height = defaultHeight;
+  				}
 				}
 			}
 		});
@@ -825,7 +826,15 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				}
 			}
 
+			long lastMouseUpEventTime = 0;
 			public void mouseUp(MouseEvent e) {
+				long time = e.time & 0xFFFFFFFFL;
+				long diff = time - lastMouseUpEventTime;
+				if (diff < 10 && diff >= 0) {
+					return;
+				}
+				lastMouseUpEventTime = time;
+
 				TableColumnCore tc = getTableColumnByOffset(e.x);
 				TableCellSWT cell = getTableCell(e.x, e.y);
 				if (cell != null && tc != null) {
@@ -878,7 +887,6 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 					}
 				}
 
-				iMouseX = e.x;
 				try {
 					if (table.getItemCount() <= 0) {
 						return;
@@ -929,8 +937,6 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 			public void mouseMove(MouseEvent e) {
 				try {
-					iMouseX = e.x;
-
 					TableCellSWT cell = getTableCell(e.x, e.y);
 					
 					if (lastCell != null && cell != lastCell && !lastCell.isDisposed()) {
@@ -1013,9 +1019,11 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				wasSelected = selectedRowIndexes;
 
 				//System.out.println(table.getSelection().length);
-				triggerSelectionListeners(new TableRowCore[] {
-					getRow((TableItem) event.item)
-				});
+				if (selectedRowIndexes.length > 0 && event.item != null) {
+					triggerSelectionListeners(new TableRowCore[] {
+						getRow((TableItem) event.item)
+					});
+				}
 
 				triggerTabViewsDataSourceChanged();
 			}
@@ -1033,97 +1041,23 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 		// we are sent a SWT.Settings event when the language changes and
 		// when System fonts/colors change.  In both cases, invalidate
-		if (SWT.getVersion() > 3200) {
-			table.addListener(SWT.Settings, new Listener() {
-				public void handleEvent(Event e) {
-					tableInvalidate();
-				}
-			});
-		}
-
-		new TableTooltips(this, table);
-
-		table.addKeyListener(new KeyListener() {
-			public void keyPressed(KeyEvent event) {
-				Object[] listeners = listenersKey.toArray();
-				for (int i = 0; i < listeners.length; i++) {
-					KeyListener l = (KeyListener) listeners[i];
-					l.keyPressed(event);
-					if (!event.doit) {
-						lCancelSelectionTriggeredOn = SystemTime.getCurrentTime();
-						return;
-					}
-				}
-
-				if (event.keyCode == SWT.F5) {
-					if ((event.stateMask & SWT.SHIFT) > 0) {
-						runForSelectedRows(new TableGroupRowRunner() {
-							public void run(TableRowCore row) {
-								row.invalidate();
-								row.refresh(true);
-							}
-						});
-					} else {
-						sortColumn(true);
-					}
-					event.doit = false;
-					return;
-				}
-
-				int key = event.character;
-				if (key <= 26 && key > 0) {
-					key += 'a' - 1;
-				}
-
-				if (event.stateMask == SWT.MOD1) {
-					switch (key) {
-						case 'a': // CTRL+A select all Torrents
-							if ((table.getStyle() & SWT.MULTI) > 0) {
-								selectAll();
-								event.doit = false;
-							}
-							break;
-
-						case '+': {
-							if (Constants.isUnix) {
-								TableColumn[] tableColumnsSWT = table.getColumns();
-								for (int i = 0; i < tableColumnsSWT.length; i++) {
-									TableColumnCore tc = (TableColumnCore) tableColumnsSWT[i].getData("TableColumnCore");
-									if (tc != null) {
-										int w = tc.getPreferredWidth();
-										if (w <= 0) {
-											w = tc.getMinWidth();
-											if (w <= 0) {
-												w = 100;
-											}
-										}
-										tc.setWidth(w);
-									}
-								}
-								event.doit = false;
-							}
-							break;
-						}
-					}
-
-					if (!event.doit) {
-						return;
-					}
-				}
+		table.addListener(SWT.Settings, new Listener() {
+			public void handleEvent(Event e) {
+				tableInvalidate();
 			}
+		});
 
-			public void keyReleased(KeyEvent event) {
-				calculateClientArea();
-				visibleRowsChanged();
+		new TableTooltips(this, table);
 
-				Object[] listeners = listenersKey.toArray();
-				for (int i = 0; i < listeners.length; i++) {
-					KeyListener l = (KeyListener) listeners[i];
-					l.keyReleased(event);
-					if (!event.doit) {
-						return;
-					}
+		table.addKeyListener(this);
+		
+		table.addDisposeListener(new DisposeListener(){
+			public void widgetDisposed(DisposeEvent e) {
+				if (filter != null && filter.widget != null && !filter.widget.isDisposed()) {
+					filter.widget.removeKeyListener(TableViewSWTImpl.this);
+					filter.widget.removeModifyListener(filter.widgetModifyListener);
 				}
+				Utils.disposeSWTObjects(new Object[] { slider } );
 			}
 		});
 
@@ -1153,6 +1087,123 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		initializeTableColumns(table);
 	}
 
+	public void keyPressed(KeyEvent event) {
+		// Note: Both table key presses and txtFilter keypresses go through this
+		//       method.
+
+		Object[] listeners = listenersKey.toArray();
+		for (int i = 0; i < listeners.length; i++) {
+			KeyListener l = (KeyListener) listeners[i];
+			l.keyPressed(event);
+			if (!event.doit) {
+				lCancelSelectionTriggeredOn = SystemTime.getCurrentTime();
+				return;
+			}
+		}
+
+		if (event.keyCode == SWT.F5) {
+			if ((event.stateMask & SWT.SHIFT) > 0) {
+				runForSelectedRows(new TableGroupRowRunner() {
+					public void run(TableRowCore row) {
+						row.invalidate();
+						row.refresh(true);
+					}
+				});
+			} else {
+				sortColumn(true);
+			}
+			event.doit = false;
+			return;
+		}
+
+		int key = event.character;
+		if (key <= 26 && key > 0) {
+			key += 'a' - 1;
+		}
+
+		if (event.stateMask == SWT.MOD1) {
+			switch (key) {
+				case 'a': // CTRL+A select all Torrents
+					if (filter == null || event.widget != filter.widget) {
+						if ((table.getStyle() & SWT.MULTI) > 0) {
+							selectAll();
+							event.doit = false;
+						}
+					} else {
+						filter.widget.selectAll();
+						event.doit = false;
+					}
+					break;
+
+				case '+': {
+					if (Constants.isUnix) {
+						TableColumn[] tableColumnsSWT = table.getColumns();
+						for (int i = 0; i < tableColumnsSWT.length; i++) {
+							TableColumnCore tc = (TableColumnCore) tableColumnsSWT[i].getData("TableColumnCore");
+							if (tc != null) {
+								int w = tc.getPreferredWidth();
+								if (w <= 0) {
+									w = tc.getMinWidth();
+									if (w <= 0) {
+										w = 100;
+									}
+								}
+								tc.setWidth(w);
+							}
+						}
+						event.doit = false;
+					}
+					break;
+				}
+				case 'f': // CTRL+F Find/Filter
+					openFilterDialog();
+					event.doit = false;
+					break;
+				case 'x': // CTRL+X: RegEx search switch
+					if (filter != null && event.widget == filter.widget) {
+						filter.regex = !filter.regex;
+						filter.widget.setBackground(filter.regex?COLOR_FILTER_REGEX:null);
+						event.doit = false;
+						refilter();
+					}
+					break;
+			}
+
+		}
+
+		if (event.stateMask == 0) {
+			if (filter != null && filter.widget == event.widget) {
+				if (event.keyCode == SWT.ARROW_DOWN) {
+					setFocus();
+					event.doit = false;
+				} else if (event.character == 13) {
+					refilter();
+				}
+			}
+		}
+		
+		if (!event.doit) {
+			return;
+		}
+
+		handleSearchKeyPress(event);
+	}
+
+	public void keyReleased(KeyEvent event) {
+		calculateClientArea();
+		visibleRowsChanged();
+
+		Object[] listeners = listenersKey.toArray();
+		for (int i = 0; i < listeners.length; i++) {
+			KeyListener l = (KeyListener) listeners[i];
+			l.keyReleased(event);
+			if (!event.doit) {
+				return;
+			}
+		}
+	}
+	
+	
 	public boolean getHeaderVisible() {
 		return headerVisible;
 	}
@@ -1260,6 +1311,8 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	private SourceReplaceListener cellEditNotifier;
 
+	private Scale slider;
+
 	private void editCell(final int column, final int row) {
 		Text oldInput = (Text) editor.getEditor();
 		if (column >= table.getColumnCount() || row < 0
@@ -1443,11 +1496,11 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		event.skipCoreFunctionality = false;
 		if (cell != null) {
 			Rectangle r = cell.getBounds();
-			event.x = e.x - r.x + VerticalAligner.getTableAdjustHorizontallyBy(table);
+			event.x = e.x - r.x;
 			if (!allowOOB && event.x < 0) {
 				return null;
 			}
-			event.y = e.y - r.y + VerticalAligner.getTableAdjustVerticalBy(table);
+			event.y = e.y - r.y;
 			if (!allowOOB && event.y < 0) {
 				return null;
 			}
@@ -1464,6 +1517,16 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			if (event.gc.getClipping().isEmpty()) {
 				return;
 			}
+			//System.out.println("paintItem " + event.gc.getClipping());
+			if (DEBUG_CELL_CHANGES) {
+  			Random random = new Random(SystemTime.getCurrentTime() / 500);
+  			event.gc.setBackground(ColorCache.getColor(event.gc.getDevice(), 
+  					210 + random.nextInt(45), 
+  					210 + random.nextInt(45), 
+  					210 + random.nextInt(45)));
+  			event.gc.fillRectangle(event.gc.getClipping());
+			}
+
 			TableItem item = (TableItem) event.item;
 			if (item == null || item.isDisposed()) {
 				return;
@@ -1546,15 +1609,20 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 			Rectangle clipping = new Rectangle(cellBounds.x, cellBounds.y,
 					cellBounds.width, cellBounds.height);
-			int headerHeight = table.getHeaderHeight();
-			int iMinY = headerHeight + clientArea.y;
-			if (clipping.y < iMinY) {
-				clipping.height -= iMinY - clipping.y;
-				clipping.y = iMinY;
-			}
-			int iMaxY = clientArea.height + clientArea.y;
-			if (clipping.y + clipping.height > iMaxY) {
-				clipping.height = iMaxY - clipping.y + 1;
+			// Cocoa calls paintitem while row is below tablearea, and painting there
+			// is valid!
+			if (!Utils.isCocoa) {
+				int headerHeight = table.getHeaderHeight();
+				int iMinY = headerHeight + clientArea.y;
+
+  			if (clipping.y < iMinY) {
+  				clipping.height -= iMinY - clipping.y;
+  				clipping.y = iMinY;
+  			}
+  			int iMaxY = clientArea.height + clientArea.y;
+  			if (clipping.y + clipping.height > iMaxY) {
+  				clipping.height = iMaxY - clipping.y + 1;
+  			}
 			}
 
 			if (clipping.width <= 0 || clipping.height <= 0) {
@@ -1573,7 +1641,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			} else if (text.length() > 0) {
 				int ofsx = 0;
 				Image image = item.getImage(event.index);
-				if (image != null) {
+				if (image != null && !image.isDisposed()) {
 					int ofs = image.getBounds().width;
 					ofsx += ofs;
 					cellBounds.x += ofs;
@@ -1684,10 +1752,8 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	protected void initializeTableColumns(final Table table) {
 		TableColumn[] oldColumns = table.getColumns();
 
-		if (SWT.getVersion() >= 3100) {
-			for (int i = 0; i < oldColumns.length; i++) {
-				oldColumns[i].removeListener(SWT.Move, columnMoveListener);
-			}
+		for (int i = 0; i < oldColumns.length; i++) {
+			oldColumns[i].removeListener(SWT.Move, columnMoveListener);
 		}
 
 		for (int i = oldColumns.length - 1; i >= 0; i--) {
@@ -1829,22 +1895,10 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 		// Add move listener at the very end, so we don't get a bazillion useless 
 		// move triggers
-		if (SWT.getVersion() >= 3100) {
-			Listener columnResizeListener = (!COLUMN_CLICK_DELAY) ? null
-					: new Listener() {
-						public void handleEvent(Event event) {
-							lLastColumnResizeOn = System.currentTimeMillis();
-						}
-					};
-
-			TableColumn[] columns = table.getColumns();
-			for (int i = 0; i < columns.length; i++) {
-				TableColumn column = columns[i];
-				column.addListener(SWT.Move, columnMoveListener);
-				if (COLUMN_CLICK_DELAY) {
-					column.addListener(SWT.Resize, columnResizeListener);
-				}
-			}
+		TableColumn[] columns = table.getColumns();
+		for (int i = 0; i < columns.length; i++) {
+			TableColumn column = columns[i];
+			column.addListener(SWT.Move, columnMoveListener);
 		}
 
 		columnVisibilitiesChanged = true;
@@ -2029,6 +2083,16 @@ public class TableViewSWTImpl<DATASOURCETYPE>
   
   		}
 		}
+
+		if (filter != null) {
+  		final MenuItem itemFilter = new MenuItem(menu, SWT.PUSH);
+  		Messages.setLanguageText(itemFilter, "MyTorrentsView.menu.filter");
+  		itemFilter.addListener(SWT.Selection, new Listener() {
+  			public void handleEvent(Event event) {
+  				openFilterDialog();
+  			}
+  		});
+		}
 	}
 
 	void showColumnEditor() {
@@ -2163,7 +2227,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	public void refreshSelectedSubView() {
 		IView view = getActiveSubView();
-		if (view != null) {
+		if (view != null && view.getComposite().isVisible()) {
 			view.refresh();
 		}
 	}
@@ -2201,20 +2265,6 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				return;
 			}
 
-			if (checkColumnWidthsEvery != 0
-					&& (loopFactor % checkColumnWidthsEvery) == 0) {
-				TableColumn[] tableColumnsSWT = table.getColumns();
-				for (int i = 0; i < tableColumnsSWT.length; i++) {
-					TableColumnCore tc = (TableColumnCore) tableColumnsSWT[i].getData("TableColumnCore");
-					if (tc != null && tc.getWidth() != tableColumnsSWT[i].getWidth()) {
-						tc.setWidth(tableColumnsSWT[i].getWidth());
-
-						int columnNumber = table.indexOf(tableColumnsSWT[i]);
-						locationChanged(columnNumber);
-					}
-				}
-			}
-
 			if (columnVisibilitiesChanged == true) {
 				updateColumnVisibilities();
 			}
@@ -2406,18 +2456,29 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		}
 	}
 
-	// @see com.aelitis.azureus.ui.common.table.TableView#addDataSource(java.lang.Object, boolean)
-	public void addDataSource(DATASOURCETYPE datasource, boolean immediate) {
-		addDataSource(datasource);
-	}
-
 	// see common.TableView
 	public void addDataSource(DATASOURCETYPE dataSource) {
+		addDataSource(dataSource, false);
+	}
+
+	private void addDataSource(DATASOURCETYPE dataSource, boolean skipFilterCheck) {
 
 		if (dataSource == null) {
 			return;
 		}
 
+		listUnfilteredDatasources_mon.enter();
+		try {
+			listUnfilteredDataSources.add(dataSource);
+		} finally {
+			listUnfilteredDatasources_mon.exit();
+		}
+
+		if (!skipFilterCheck && filter != null
+				&& !filter.checker.filterCheck(dataSource, filter.text, filter.regex)) {
+			return;
+		}
+
 		if (Utils.IMMEDIATE_ADDREMOVE_DELAY == 0) {
 			reallyAddDataSources(new Object[] {
 				dataSource
@@ -2455,12 +2516,32 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	// see common.TableView
 	public void addDataSources(final DATASOURCETYPE dataSources[]) {
+		addDataSources(dataSources, false);
+	}
+
+	public void addDataSources(final DATASOURCETYPE dataSources[],
+			boolean skipFilterCheck) {
 
 		if (dataSources == null) {
 			return;
 		}
 
+		listUnfilteredDatasources_mon.enter();
+		try {
+			listUnfilteredDataSources.addAll(Arrays.asList(dataSources));
+		} finally {
+			listUnfilteredDatasources_mon.exit();
+		}
+
 		if (Utils.IMMEDIATE_ADDREMOVE_DELAY == 0) {
+			if (!skipFilterCheck && filter!= null) {
+  			for (int i = 0; i < dataSources.length; i++) {
+  				if (!filter.checker.filterCheck(dataSources[i], filter.text,
+  						filter.regex)) {
+  					dataSources[i] = null;
+  				}
+  			}
+			}
 			reallyAddDataSources(dataSources);
 			return;
 		}
@@ -2478,6 +2559,12 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				if (dataSources[i] == null) {
 					continue;
 				}
+				if (!skipFilterCheck
+						&& filter != null
+						&& !filter.checker.filterCheck(dataSources[i], filter.text,
+								filter.regex)) {
+					continue;
+				}
 				boolean alreadyThere = dataSourcesToAdd.contains(dataSources[i]);
 				if (alreadyThere) {
 					// added twice.. ensure it's not in the remove list
@@ -2519,7 +2606,9 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	}
 
 	private void reallyAddDataSources(final Object dataSources[]) {
-
+		// Note: We assume filterCheck has already run, and the list of dataSources
+		//       all passed the filter
+		
 		if (mainComposite == null || table == null || mainComposite.isDisposed()
 				|| table.isDisposed()) {
 			return;
@@ -2827,17 +2916,19 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		mainComposite.getParent().setCursor(null);
 	}
 
-	// @see com.aelitis.azureus.ui.common.table.TableView#removeDataSource(java.lang.Object, boolean)
-	public void removeDataSource(DATASOURCETYPE dataSource, boolean immediate) {
-		removeDataSource( dataSource );
-	}
-
 	// @see com.aelitis.azureus.ui.common.table.TableView#removeDataSource(java.lang.Object)
 	public void removeDataSource(final DATASOURCETYPE dataSource) {
 		if (dataSource == null) {
 			return;
 		}
 
+		listUnfilteredDatasources_mon.enter();
+		try {
+			listUnfilteredDataSources.remove(dataSource);
+		} finally {
+			listUnfilteredDatasources_mon.exit();
+		}
+
 		if (Utils.IMMEDIATE_ADDREMOVE_DELAY == 0) {
 			reallyRemoveDataSources(new Object[]{dataSource});
 			return;
@@ -2864,10 +2955,17 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	 * @param bImmediate Remove immediately, or queue and remove at next refresh
 	 */
 	public void removeDataSources(final DATASOURCETYPE[] dataSources) {
-		if (dataSources == null) {
+		if (dataSources == null || dataSources.length == 0) {
 			return;
 		}
 
+		listUnfilteredDatasources_mon.enter();
+		try {
+			listUnfilteredDataSources.removeAll(Arrays.asList(dataSources));
+		} finally {
+			listUnfilteredDatasources_mon.exit();
+		}
+
 		if (Utils.IMMEDIATE_ADDREMOVE_DELAY == 0) {
 			reallyRemoveDataSources(dataSources);
 			return;
@@ -3043,13 +3141,11 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				mapDataSourceToRow.remove(dataSources[i]);
 				if (item != null) {
 					sortedRows.remove(item);
-					item.delete();
 				}
 			}
 
-			fillRowGaps(false);
 			if (DEBUGADDREMOVE) {
-				debug("<< Remove 1 row, noswt");
+				debug("<< Remove row(s), noswt");
 			}
 		}
 	}
@@ -3728,30 +3824,6 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		 * @param event event information
 		 */
 		public void handleEvent(final Event event) {
-			if (COLUMN_CLICK_DELAY) {
-				// temporary for OSX.. resizing column triggers selection, so cancel
-				// if a resize was recent. 
-				final Timer timer = new Timer("Column Selection Wait");
-				timer.addEvent(System.currentTimeMillis() + 85,
-						new TimerEventPerformer() {
-							public void perform(TimerEvent timerEvent) {
-								Utils.execSWTThread(new AERunnable() {
-									public void runSupport() {
-										if (lLastColumnResizeOn == -1
-												|| System.currentTimeMillis() - lLastColumnResizeOn > 220) {
-											reallyHandleEvent(event);
-										}
-									}
-								});
-								timer.destroy();
-							}
-						});
-			} else {
-				reallyHandleEvent(event);
-			}
-		}
-
-		private void reallyHandleEvent(Event event) {
 			TableColumn column = (TableColumn) event.widget;
 			if (column == null) {
 				return;
@@ -3979,7 +4051,9 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		} else {
 			ptIconSize.y = iHeight;
 		}
-		bSkipFirstColumn = true;
+		if (!Constants.isOSX) {
+			bSkipFirstColumn = true;
+		}
 	}
 
 	public int getRowDefaultHeight() {
@@ -3992,7 +4066,9 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	// from common.TableView
 	public void setRowDefaultIconSize(Point size) {
 		ptIconSize = size;
-		bSkipFirstColumn = true;
+		if (!Constants.isOSX) {
+			bSkipFirstColumn = true;
+		}
 	}
 
 	// TabViews Functions
@@ -4258,15 +4334,12 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			return false;
 		}
 		int i = row.getIndex();
-		if (Utils.SWT32_TABLEPAINT) {
-			int iTopIndex = table.getTopIndex();
-			if (iTopIndex < 0) {
-				return false;
-			}
-			int iBottomIndex = Utils.getTableBottomIndex(table, iTopIndex);
-			return i >= iTopIndex && i <= iBottomIndex;
+		int iTopIndex = table.getTopIndex();
+		if (iTopIndex < 0) {
+			return false;
 		}
-		return i >= lastTopIndex && i <= lastBottomIndex;
+		int iBottomIndex = Utils.getTableBottomIndex(table, iTopIndex);
+		return i >= iTopIndex && i <= iBottomIndex;
 	}
 
 	private void visibleRowsChanged() {
@@ -4645,12 +4718,11 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		pt = table.toControl(pt);
 
 		Rectangle bounds = tableCell.getBounds();
-		int x = pt.x - bounds.x
-				+ VerticalAligner.getTableAdjustHorizontallyBy(table);
+		int x = pt.x - bounds.x;
 		if (x < 0 || x > bounds.width) {
 			return null;
 		}
-		int y = pt.y - bounds.y + VerticalAligner.getTableAdjustVerticalBy(table);
+		int y = pt.y - bounds.y;
 		if (y < 0 || y > bounds.height) {
 			return null;
 		}
@@ -4728,6 +4800,16 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 					}
 				});
 				loopFactor = 0;
+
+				IView view = getActiveSubView();
+				if (view instanceof IViewExtension) {
+					((IViewExtension)view).viewActivated();
+				}
+			} else {
+				IView view = getActiveSubView();
+				if (view instanceof IViewExtension) {
+					((IViewExtension)view).viewDeactivated();
+				}
 			}
 		}
 		return isVisible;
@@ -4747,4 +4829,281 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	public void setMenuEnabled(boolean menuEnabled) {
 		this.menuEnabled = menuEnabled;
 	}
+
+	private void openFilterDialog() {
+		if (filter == null) {
+			return;
+		}
+		SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow();
+		entryWindow.initTexts("MyTorrentsView.dialog.setFilter.title", null,
+				"MyTorrentsView.dialog.setFilter.text", new String[] {
+					MessageText.getString(getTableID() + "View" + ".header")
+				});
+		entryWindow.setPreenteredText(filter.text, false);
+		entryWindow.prompt();
+		if (!entryWindow.hasSubmittedInput()) {
+			return;
+		}
+		String message = entryWindow.getSubmittedInput();
+
+		if (message == null) {
+			message = "";
+		}
+
+		setFilterText(message);
+	}
+
+	private void handleSearchKeyPress(KeyEvent e) {
+		if (filter == null || e.widget == filter.widget) {
+			return;
+		}
+
+		String newText = null;
+
+		// normal character: jump to next item with a name beginning with this character
+		if (ASYOUTYPE_MODE == ASYOUTYPE_MODE_FIND) {
+			if (System.currentTimeMillis() - filter.lastFilterTime > 3000)
+				newText = "";
+		}
+
+		if (e.keyCode == SWT.BS) {
+			if (e.stateMask == SWT.CONTROL) {
+				newText = "";
+			} else if (filter.nextText.length() > 0) {
+				newText = filter.nextText.substring(0, filter.nextText.length() - 1);
+			}
+		} else if ((e.stateMask & ~SWT.SHIFT) == 0 && e.character > 0) {
+			newText = filter.nextText + String.valueOf(e.character);
+		}
+
+		if (newText == null) {
+			return;
+		}
+
+		if (ASYOUTYPE_MODE == ASYOUTYPE_MODE_FILTER) {
+			if (filter != null && filter.widget != null && !filter.widget.isDisposed()) {
+				filter.widget.setFocus();
+			}
+			setFilterText(newText);
+		} else {
+			TableCellCore[] cells = getColumnCells("name");
+
+			//System.out.println(sLastSearch);
+
+			Arrays.sort(cells, TableCellImpl.TEXT_COMPARATOR);
+			int index = Arrays.binarySearch(cells, filter.text,
+					TableCellImpl.TEXT_COMPARATOR);
+			if (index < 0) {
+
+				int iEarliest = -1;
+				String s = filter.regex ? filter.text : "\\Q" + filter.text + "\\E";
+				Pattern pattern = Pattern.compile(s, Pattern.CASE_INSENSITIVE);
+				for (int i = 0; i < cells.length; i++) {
+					Matcher m = pattern.matcher(cells[i].getText());
+					if (m.find() && (m.start() < iEarliest || iEarliest == -1)) {
+						iEarliest = m.start();
+						index = i;
+					}
+				}
+
+				if (index < 0)
+					// Insertion Point (best guess)
+					index = -1 * index - 1;
+			}
+
+			if (index >= 0) {
+				if (index >= cells.length)
+					index = cells.length - 1;
+				TableRowCore row = cells[index].getTableRowCore();
+				int iTableIndex = row.getIndex();
+				if (iTableIndex >= 0) {
+					setSelectedRows(new TableRowCore[] {
+						row
+					});
+				}
+			}
+			filter.lastFilterTime = System.currentTimeMillis();
+		}
+		e.doit = false;
+	}
+
+	public void setFilterText(String s) {
+		if (filter == null) {
+			return;
+		}
+		filter.nextText = s;
+		if (filter != null && filter.widget != null && !filter.widget.isDisposed()) {
+			if (!filter.nextText.equals(filter.widget.getText())) {
+				filter.widget.setText(filter.nextText);
+				filter.widget.setSelection(filter.nextText.length());
+			}
+
+			if (filter.regex) {
+				try {
+					Pattern.compile(filter.nextText, Pattern.CASE_INSENSITIVE);
+					filter.widget.setBackground(COLOR_FILTER_REGEX);
+					Messages.setLanguageTooltip(filter.widget,
+							"MyTorrentsView.filter.tooltip");
+				} catch (Exception e) {
+					filter.widget.setBackground(Colors.colorErrorBG);
+					filter.widget.setToolTipText(e.getMessage());
+				}
+			} else {
+				filter.widget.setBackground(null);
+				Messages.setLanguageTooltip(filter.widget,
+						"MyTorrentsView.filter.tooltip");
+			}
+		}
+
+		if (filter.eventUpdate != null) {
+			filter.eventUpdate.cancel();
+		}
+		filter.eventUpdate = SimpleTimer.addEvent("SearchUpdate",
+				SystemTime.getOffsetTime(ASYOUTYPE_UPDATEDELAY),
+				new TimerEventPerformer() {
+					public void perform(TimerEvent event) {
+						if (filter.eventUpdate.isCancelled()) {
+							filter.eventUpdate = null;
+							return;
+						}
+						filter.eventUpdate = null;
+						if (filter.nextText != null && !filter.nextText.equals(filter.text)) {
+							filter.text = filter.nextText;
+							filter.checker.filterSet(filter.text);
+							refilter();
+						}
+					}
+				});
+	}
+
+	public String getFilterText() {
+		return filter == null ? "" : filter.text;
+	}
+
+	@SuppressWarnings("unchecked")
+	public void refilter() {
+		if (filter == null) {
+			return;
+		}
+		if (filter.eventUpdate != null) {
+			filter.eventUpdate.cancel();
+		}
+		filter.eventUpdate = null;
+
+		listUnfilteredDatasources_mon.enter();
+		try {
+			DATASOURCETYPE[] unfilteredArray = (DATASOURCETYPE[]) listUnfilteredDataSources.toArray();
+
+			boolean all = filter.text.length() == 0;
+
+			Set<DATASOURCETYPE> existing = new HashSet<DATASOURCETYPE>(
+					getDataSources());
+			List<DATASOURCETYPE> listRemoves = new ArrayList<DATASOURCETYPE>();
+			List<DATASOURCETYPE> listAdds = new ArrayList<DATASOURCETYPE>();
+
+			for (int i = 0; i < unfilteredArray.length; i++) {
+				boolean bHave = existing.contains(unfilteredArray[i]);
+				boolean isOurs = all ? true : filter.checker.filterCheck(
+						unfilteredArray[i], filter.text, filter.regex);
+				if (!isOurs) {
+					if (bHave) {
+						listRemoves.add(unfilteredArray[i]);
+					}
+				} else {
+					if (!bHave) {
+						listAdds.add(unfilteredArray[i]);
+					}
+				}
+			}
+			removeDataSources((DATASOURCETYPE[]) listRemoves.toArray());
+			addDataSources((DATASOURCETYPE[]) listAdds.toArray(), true);
+
+			// add back the ones removeDataSources removed
+			listUnfilteredDataSources.addAll(listRemoves);
+		} finally {
+			listUnfilteredDatasources_mon.exit();
+			processDataSourceQueue();
+		}
+	}
+
+	public void enableFilterCheck(Text txtFilter,
+			TableViewFilterCheck<DATASOURCETYPE> filterCheck) {
+		if (filter != null) {
+			if (filter.widget != null && !filter.widget.isDisposed()) {
+				filter.widget.removeKeyListener(TableViewSWTImpl.this);
+				filter.widget.removeModifyListener(filter.widgetModifyListener);
+			}
+		} else{
+			filter = new filter();
+		}
+		filter.widget = txtFilter;
+		if (txtFilter != null) {
+  		txtFilter.addKeyListener(this);
+  
+  		filter.widgetModifyListener = new ModifyListener() {
+  			public void modifyText(ModifyEvent e) {
+  				setFilterText(((Text) e.widget).getText());
+  			}
+  		};
+  		txtFilter.addModifyListener(filter.widgetModifyListener);
+  		
+  		if (txtFilter.getText().length() == 0) {
+  			txtFilter.setText(filter.text);
+  		} else {
+  			filter.text = filter.nextText = txtFilter.getText();
+  		}
+		} else {
+			filter.text = filter.nextText = "";
+		}
+		
+		filter.checker = filterCheck;
+
+		filter.checker.filterSet(filter.text);
+		refilter();
+	}
+
+	public boolean enableSizeSlider(Composite composite, int min, int max) {
+		try {
+			if (slider != null && !slider.isDisposed()) {
+				slider.dispose();
+			}
+			final Method method = Table.class.getDeclaredMethod("setItemHeight", new Class<?>[] {
+				int.class
+			});
+			method.setAccessible(true);
+
+			composite.setLayout(new FormLayout());
+			slider = new Scale(composite, SWT.HORIZONTAL);
+			slider.setMinimum(min);
+			slider.setMaximum(max);
+			slider.setSelection(getRowDefaultHeight());
+			try {
+				method.invoke(table, new Object[] { slider.getSelection() } );
+			} catch (Throwable e1) {
+			}
+			slider.addSelectionListener(new SelectionListener() {
+				public void widgetSelected(SelectionEvent e) {
+					setRowDefaultHeight(slider.getSelection());
+					try {
+						method.invoke(table, new Object[] { slider.getSelection() } );
+					} catch (Throwable e1) {
+						e1.printStackTrace();
+					}
+					tableInvalidate();
+				}
+				
+				public void widgetDefaultSelected(SelectionEvent e) {
+				}
+			});
+			slider.setLayoutData(Utils.getFilledFormData());
+			composite.layout();
+		} catch (Throwable t) {
+			return false;
+		}
+		return true;
+	}
+	
+	public void disableSizeSlider() {
+		Utils.disposeSWTObjects(new Object[] { slider });
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableViewTab.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewTab.java
index c9e86e5..ca97cdc 100644
--- a/org/gudy/azureus2/ui/swt/views/table/impl/TableViewTab.java
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewTab.java
@@ -1,64 +1,104 @@
 package org.gudy.azureus2.ui.swt.views.table.impl;
 
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
 
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.IndentWriter;
 import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.ui.swt.views.IViewExtension;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
 
-public class TableViewTab extends AbstractIView
+public abstract class TableViewTab<DATASOURCETYPE>
+	extends AbstractIView
+	implements IViewExtension
 {
-	private TableViewSWT tv;
+	private TableViewSWT<DATASOURCETYPE> tv;
+	private Object parentDataSource;
+	private final String propertiesPrefix;
+	private Composite composite;
 
-	public void setTableView(TableViewSWT tv) {
-		this.tv = tv;
+	
+	public TableViewTab(String propertiesPrefix) {
+		this.propertiesPrefix = propertiesPrefix;
 	}
 	
-	public TableViewSWT getTableView() {
+	public TableViewSWT<DATASOURCETYPE> getTableView() {
 		return tv;
 	}
 
 	public final void initialize(Composite composite) {
-		tv.initialize(composite);
+		tv = initYourTableView();
+		Composite parent = initComposite(composite);
+		tv.initialize(parent);
+		if (parent != composite) {
+			this.composite = composite;
+		} else {
+			this.composite = tv.getComposite();
+		}
+		
+		tableViewTabInitComplete();
+		if (parentDataSource != null) {
+			tv.setParentDataSource(parentDataSource);
+		}
+	}
+	
+	public void tableViewTabInitComplete() {
 	}
 
+	public Composite initComposite(Composite composite) {
+		return composite;
+	}
+
+	public abstract TableViewSWT<DATASOURCETYPE> initYourTableView();
+
 	public final void dataSourceChanged(Object newDataSource) {
-		tv.setParentDataSource(newDataSource);
+		this.parentDataSource = newDataSource;
+		if (tv != null) {
+			tv.setParentDataSource(newDataSource);
+		}
 	}
 
 	public void updateLanguage() {
 		super.updateLanguage();
-		tv.updateLanguage();
+		if (tv != null) {
+			tv.updateLanguage();
+		}
 	}
 
 	public final void refresh() {
-		tv.refreshTable(false);
+		if (tv != null) {
+			tv.refreshTable(false);
+		}
 	}
 
 	// @see org.gudy.azureus2.ui.swt.views.AbstractIView#delete()
 	public final void delete() {
-		tv.delete();
+		if (tv != null) {
+			tv.delete();
+		}
 		super.delete();
 	}
 
 	// @see org.gudy.azureus2.ui.swt.views.AbstractIView#getData()
 	public final String getData() {
-		return tv.getPropertiesPrefix() + ".title.short";
+		return getPropertiesPrefix() + ".title.short";
 	}
 
 	public final String getFullTitle() {
-		return MessageText.getString(tv.getPropertiesPrefix() + ".title.full");
+		return MessageText.getString(getPropertiesPrefix() + ".title.full");
 	}
 
 	// @see org.gudy.azureus2.ui.swt.views.AbstractIView#generateDiagnostics(org.gudy.azureus2.core3.util.IndentWriter)
 	public final void generateDiagnostics(IndentWriter writer) {
-		tv.generate(writer);
+		if (tv != null) {
+			tv.generate(writer);
+		}
 	}
 	
 	// @see org.gudy.azureus2.ui.swt.views.AbstractIView#getComposite()
 	public Composite getComposite() {
-		return tv.getComposite();
+		return composite;
 	}
 	
 	public void itemActivated(String itemKey) {
@@ -73,5 +113,26 @@ public class TableViewTab extends AbstractIView
 		if (itemKey.equals("editcolumns")) {return true;}
 		return false;
 	}
-		
+
+	public String getPropertiesPrefix() {
+		return propertiesPrefix;
+	}
+	
+	public Menu getPrivateMenu() {
+		return null;
+	}
+	
+	public void viewActivated() {
+		// cheap hack.. calling isVisible freshens table's visible status (and
+		// updates subviews)
+		if (tv instanceof TableViewSWTImpl) {
+			((TableViewSWTImpl)tv).isVisible();
+		}
+	}
+	
+	public void viewDeactivated() {
+		if (tv instanceof TableViewSWTImpl) {
+			((TableViewSWTImpl)tv).isVisible();
+		}
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnCreator.java b/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnCreator.java
index 5ea7cdd..646b10e 100644
--- a/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnCreator.java
+++ b/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnCreator.java
@@ -21,25 +21,22 @@
 package org.gudy.azureus2.ui.swt.views.table.utils;
 
 import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 import java.util.Iterator;
 import java.util.Map;
 
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.LightHashMap;
-import org.gudy.azureus2.ui.swt.views.columnsetup.*;
+import org.gudy.azureus2.plugins.download.DownloadTypeComplete;
+import org.gudy.azureus2.plugins.download.DownloadTypeIncomplete;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+import org.gudy.azureus2.ui.swt.views.columnsetup.ColumnTC_ChosenColumn;
+import org.gudy.azureus2.ui.swt.views.columnsetup.ColumnTC_NameInfo;
+import org.gudy.azureus2.ui.swt.views.columnsetup.ColumnTC_Sample;
 import org.gudy.azureus2.ui.swt.views.table.TableColumnCoreCreationListener;
 import org.gudy.azureus2.ui.swt.views.tableitems.mytorrents.*;
 
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
 
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.download.DownloadTypeComplete;
-import org.gudy.azureus2.plugins.download.DownloadTypeIncomplete;
-import org.gudy.azureus2.plugins.ui.tables.TableColumn;
-import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
-
 /**
  * @author TuxPaper
  * @created Dec 19, 2007
@@ -73,6 +70,8 @@ public class TableColumnCreator
 		TableColumnManager tcManager = TableColumnManager.getInstance();
 		Map mapTCs = tcManager.getTableColumnsAsMap(DownloadTypeIncomplete.class, tableID);
 
+		tcManager.setDefaultColumnNames(tableID, defaultVisibleOrder);
+
 		if (!tcManager.loadTableColumnSettings(DownloadTypeIncomplete.class,
 				tableID)
 				|| areNoneVisible(mapTCs)) {
@@ -110,6 +109,8 @@ public class TableColumnCreator
 		TableColumnManager tcManager = TableColumnManager.getInstance();
 		Map mapTCs = tcManager.getTableColumnsAsMap(DownloadTypeComplete.class, tableID);
 
+		tcManager.setDefaultColumnNames(tableID, defaultVisibleOrder);
+
 		if (!tcManager.loadTableColumnSettings(DownloadTypeComplete.class,
 				tableID)
 				|| areNoneVisible(mapTCs)) {
diff --git a/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnManager.java b/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnManager.java
index fcfc8c0..c094802 100644
--- a/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnManager.java
+++ b/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnManager.java
@@ -77,10 +77,16 @@ public class TableColumnManager {
    * or {@link #saveTableConfigs()}
    */
 	private Map mapTablesConfig;
+	private long lastTableConfigAccess;
 	private static Comparator orderComparator;
 	
-	private Map<String, TableColumnCreationListener> mapColumnIDsToListener = new LightHashMap();
-	private Map<Class, List> mapDataSourceTypeToColumnIDs = new LightHashMap();
+	private Map<String, TableColumnCreationListener> mapColumnIDsToListener = new LightHashMap<String, TableColumnCreationListener>();
+	private Map<Class, List> mapDataSourceTypeToColumnIDs = new LightHashMap<Class, List>();
+
+	/**
+	 * key = TableID; value = table column ids
+	 */
+	private Map<String, String[]> mapTableDefaultColumns = new LightHashMap<String, String[]>();
 
 	static {
 		orderComparator = new Comparator() {
@@ -145,6 +151,7 @@ public class TableColumnManager {
 					Map mapColumnConfig = getTableConfigMap(sTableID);
 					((TableColumnCore) item).loadSettings(mapColumnConfig);
 				}
+				
 				if (!item.getColumnAdded()) {
 					item.setColumnAdded(true);
 				}
@@ -225,6 +232,15 @@ public class TableColumnManager {
 		return (TableColumnCore[]) mTypes.values().toArray(
 				new TableColumnCore[mTypes.values().size()]);
 	}
+  
+  public String[] getDefaultColumnNames(String tableID) {
+  	String[] columnNames = mapTableDefaultColumns.get(tableID);
+  	return columnNames;
+  }
+  
+  public void setDefaultColumnNames(String tableID, String[] columnNames) {
+  	mapTableDefaultColumns.put(tableID, columnNames);
+  }
 
   /*
   private Map getAllTableColumnCore(
@@ -368,7 +384,9 @@ public class TableColumnManager {
 						tc = new TableColumnImpl(forDataSourceType, tableID, columnID);
 					}
 
-					l.tableColumnCreated(tc);
+					if (l != null) {
+						l.tableColumnCreated(tc);
+					}
 
 					addColumns(new TableColumnCore[] {
 						tc
@@ -504,16 +522,36 @@ public class TableColumnManager {
   
   public Map getTableConfigMap(String sTableID) {
 		synchronized (this) {
+			lastTableConfigAccess = SystemTime.getMonotonousTime();
+			
 			if (mapTablesConfig == null) {
 				mapTablesConfig = FileUtil.readResilientConfigFile(CONFIG_FILE);
 
-				// Dispose of tableconfigs after XXs.. saves up to 50k
-				SimpleTimer.addEvent("DisposeTbaleConfigMap",
-						SystemTime.getOffsetTime(30000), new TimerEventPerformer() {
-							public void perform(TimerEvent event) {
-								synchronized (this) {
-									saveTableConfigs();
-									mapTablesConfig = null;
+					// Dispose of tableconfigs after XXs.. saves up to 50k
+				
+				SimpleTimer.addEvent(
+						"DisposeTbaleConfigMap",
+						SystemTime.getOffsetTime(30000), 
+						new TimerEventPerformer() 
+						{
+							public void 
+							perform(
+								TimerEvent event ) 
+							{
+								synchronized( TableColumnManager.this ){
+									
+									long	now = SystemTime.getMonotonousTime();
+									
+									if ( now - lastTableConfigAccess > 25000 ){
+									
+										mapTablesConfig = null;
+										
+									}else{
+										SimpleTimer.addEvent(
+											"DisposeTbaleConfigMap",
+											SystemTime.getOffsetTime(30000), 
+											this );
+									}
 								}
 							}
 						});
@@ -596,13 +634,17 @@ public class TableColumnManager {
 	 */
 	public void registerColumn(Class forDataSourceType, String columnID,
 			TableColumnCreationListener listener) {
-  	mapColumnIDsToListener.put(forDataSourceType + "." + columnID, listener);
+		if (listener != null) {
+			mapColumnIDsToListener.put(forDataSourceType + "." + columnID, listener);
+		}
 		List list = (List) mapDataSourceTypeToColumnIDs.get(forDataSourceType);
 		if (list == null) {
 			list = new ArrayList(1);
 			mapDataSourceTypeToColumnIDs.put(forDataSourceType, list);
 		}
-		list.add(columnID);
+		if (!list.contains(columnID)) {
+			list.add(columnID);
+		}
 	}
 	
 	public void unregisterColumn(Class forDataSourceType, String columnID,
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/ColumnDateSizer.java b/org/gudy/azureus2/ui/swt/views/tableitems/ColumnDateSizer.java
index 5a67cea..5ffc327 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/ColumnDateSizer.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/ColumnDateSizer.java
@@ -87,7 +87,8 @@ public abstract class ColumnDateSizer
 			Number nShowTime = (Number) oShowTime;
 			showTime = nShowTime.byteValue() == 1;
 		} else {
-			showTime = COConfigurationManager.getBooleanParameter("v3.Start Advanced");
+	    int userMode = COConfigurationManager.getIntParameter("User Mode");
+			showTime = userMode > 1;
 		}
 	}
 
@@ -150,7 +151,7 @@ public abstract class ColumnDateSizer
 		}
 	}
 
-	public void recalcWidth(Date date) {
+	private void recalcWidth(Date date) {
 		String suffix = showTime && !multiline ? " hh:mm a" : "";
 
 		int width = getWidth();
@@ -208,7 +209,7 @@ public abstract class ColumnDateSizer
 		}
 	}
 
-	public int calcWidth(Date date, String format) {
+	private int calcWidth(Date date, String format) {
 		GC gc = new GC(Display.getDefault());
 		if (fontBold == null) {
 			FontData[] fontData = gc.getFont().getFontData();
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/FirstPieceItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/FirstPieceItem.java
index a5f7404..8eaab21 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/FirstPieceItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/FirstPieceItem.java
@@ -48,14 +48,26 @@ public class FirstPieceItem
 
   public void refresh(TableCell cell) {
     DiskManagerFileInfo fileInfo = (DiskManagerFileInfo)cell.getDataSource();
-    long value = (fileInfo == null) ? 0 : fileInfo.getFirstPieceNumber();
+    long sort_value;
+    
+    if ( fileInfo == null ){
+    	sort_value = 0;
+    }else{
+    	sort_value = fileInfo.getFirstPieceNumber();
+    	
+    	if ( sort_value >= 0 ){
+    		
+    		sort_value = (sort_value << 32) + fileInfo.getIndex();
+    	}
+    }
 
-    if( !cell.setSortValue( value ) && cell.isValid() ) {
+    
+    if( !cell.setSortValue( sort_value ) && cell.isValid() ) {
       return;
     }
     
 		// < 0 -> unknown skeleton value 
 	
-    cell.setText( value<0?"":(""+value));
+    cell.setText( sort_value<0?"":(""+fileInfo.getFirstPieceNumber()));
   }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/NameItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/NameItem.java
index 36c91d6..6b33b67 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/NameItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/NameItem.java
@@ -40,6 +40,7 @@ import org.gudy.azureus2.core3.util.FileUtil;
 import org.gudy.azureus2.ui.swt.ImageRepository;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.debug.ObfusticateCellText;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
@@ -197,10 +198,9 @@ public class NameItem extends CoreTableColumn implements
 		
 		if (!result[0])
 		{
-			MessageBox mb = new MessageBox(Utils.findAnyShell(), SWT.ICON_ERROR | SWT.OK);
-			mb.setText(MessageText.getString("FilesView.rename.failed.title"));
-			mb.setMessage(MessageText.getString("FilesView.rename.failed.text"));
-			mb.open();
+			new MessageBoxShell(SWT.ICON_ERROR | SWT.OK, 
+					MessageText.getString("FilesView.rename.failed.title"),
+					MessageText.getString("FilesView.rename.failed.text")).open(null);
 		}
 		
 		return true;
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/PercentItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/PercentItem.java
index 33184fd..e19eb21 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/PercentItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/PercentItem.java
@@ -55,14 +55,15 @@ public class PercentItem
     long percent = 0;
 	
     if (fileInfo != null ){
+    	long bytesDownloaded = fileInfo.getDownloaded();
 		
-		if ( fileInfo.getDownloaded() < 0 ){
+		if ( bytesDownloaded < 0 ){
 			
 			percent = -1; // unknown skeleton value
 			
 		}else if ( fileInfo.getLength() != 0 ){
 
-			percent = (1000 * fileInfo.getDownloaded()) / fileInfo.getLength();
+			percent = (1000 * bytesDownloaded) / fileInfo.getLength();
 		}
 	  
     }else{
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/CommentIconItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/CommentIconItem.java
index 56e0703..08dc527 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/CommentIconItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/CommentIconItem.java
@@ -43,7 +43,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  */
 public class CommentIconItem
        extends CoreTableColumn 
-       implements TableCellRefreshListener, TableCellMouseListener, TableCellAddedListener
+       implements TableCellRefreshListener, TableCellMouseListener, TableCellAddedListener, TableCellToolTipListener
 {
 	public static final Class DATASOURCE_TYPE = Download.class;
 
@@ -106,15 +106,26 @@ public class CommentIconItem
 	  Graphic oldGraphic = cell.getGraphic();
 	  if (comment == null && oldGraphic != noGraphicComment) {
 	  	cell.setGraphic(noGraphicComment);
-		  cell.setToolTip(null);
 		  cell.setSortValue(null);
 	  }
 	  else if (comment != null && oldGraphic != graphicComment) {
 	  	cell.setGraphic(graphicComment);
-		  cell.setToolTip(comment);
 		  cell.setSortValue(comment);
 	  }
 	  
   }
 
+  public void cellHover(TableCell cell) {
+	  DownloadManager dm = (DownloadManager)cell.getDataSource();
+	  String comment = null;
+	  if (dm != null) {
+		  comment = dm.getDownloadState().getUserComment();
+		  if (comment!=null && comment.length()==0) {comment = null;}
+	  }
+	  cell.setToolTip(comment);
+  }
+  
+  public void cellHoverComplete(TableCell cell) {
+	  cell.setToolTip(null);
+  }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/NameItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/NameItem.java
index 1f02a53..392934d 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/NameItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/NameItem.java
@@ -31,6 +31,8 @@ import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.ui.UIInputReceiver;
+import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
 import org.gudy.azureus2.plugins.ui.menus.MenuItem;
 import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
 import org.gudy.azureus2.plugins.ui.tables.*;
@@ -78,20 +80,23 @@ public class NameItem extends CoreTableColumn implements
 				Object[] o = (Object[]) target;
 				for (Object object : o) {
 					if (object instanceof DownloadManager) {
-						DownloadManager dm = (DownloadManager) object;
+						final DownloadManager dm = (DownloadManager) object;
 						String msg_key_prefix = "MyTorrentsView.menu.rename.displayed.enter.";
 
 						SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
 								msg_key_prefix + "title", msg_key_prefix + "message");
 						entryWindow.setPreenteredText(dm.getDisplayName(), false);
-						entryWindow.prompt();
-						if (!entryWindow.hasSubmittedInput()) {
-							return;
-						}
-						String value = entryWindow.getSubmittedInput();
-						if (value != null && value.length() > 0) {
-							dm.getDownloadState().setDisplayName(value);
-						}
+						entryWindow.prompt(new UIInputReceiverListener() {
+							public void UIInputReceiverClosed(UIInputReceiver entryWindow) {
+								if (!entryWindow.hasSubmittedInput()) {
+									return;
+								}
+								String value = entryWindow.getSubmittedInput();
+								if (value != null && value.length() > 0) {
+									dm.getDownloadState().setDisplayName(value);
+								}
+							}
+						});
 					}
 				}
 			}
diff --git a/org/gudy/azureus2/ui/swt/views/utils/ManagerUtils.java b/org/gudy/azureus2/ui/swt/views/utils/ManagerUtils.java
index eab6a17..de74de7 100644
--- a/org/gudy/azureus2/ui/swt/views/utils/ManagerUtils.java
+++ b/org/gudy/azureus2/ui/swt/views/utils/ManagerUtils.java
@@ -29,7 +29,6 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.MessageBox;
 import org.eclipse.swt.widgets.Shell;
-
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerState;
@@ -38,7 +37,10 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
 import org.gudy.azureus2.core3.tracker.host.TRHostException;
-import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.AERunnableBoolean;
+import org.gudy.azureus2.core3.util.AsyncDispatcher;
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.platform.PlatformManager;
 import org.gudy.azureus2.platform.PlatformManagerCapabilities;
 import org.gudy.azureus2.platform.PlatformManagerFactory;
@@ -299,26 +301,22 @@ public class ManagerUtils {
 	        numSeeds--;
 	      
 	      if (numSeeds == 0) {
-	  			stopme = Utils.execSWTThreadWithBool("stopSeeding",
-	  					new AERunnableBoolean() {
-	  						public boolean runSupport() {
-	  							String title = MessageText.getString("Content.alert.notuploaded.title");
-	  							String text = MessageText.getString("Content.alert.notuploaded.text",
-	  									new String[] {
-	  										dm.getDisplayName(),
-	  										MessageText.getString("Content.alert.notuploaded.stop")
-	  									});
-
-	  							MessageBoxShell mb = new MessageBoxShell(Utils.findAnyShell(),
-	  									title, text, new String[] {
-	  										MessageText.getString("Content.alert.notuploaded.button.stop"),
-	  										MessageText.getString("Content.alert.notuploaded.button.continue")
-	  									}, 1, null, null, false, 0);
-	  							mb.setRelatedObject(dm);
-
-	  							return mb.open() == 0;
-	  						}
-	  					});
+					String title = MessageText.getString("Content.alert.notuploaded.title");
+					String text = MessageText.getString("Content.alert.notuploaded.text",
+							new String[] {
+								dm.getDisplayName(),
+								MessageText.getString("Content.alert.notuploaded.stop")
+							});
+
+					MessageBoxShell mb = new MessageBoxShell(
+							title, text, new String[] {
+								MessageText.getString("Content.alert.notuploaded.button.stop"),
+								MessageText.getString("Content.alert.notuploaded.button.continue")
+							}, 1);
+					mb.setRelatedObject(dm);
+
+					mb.open(null);
+					stopme = mb.waitUntilClosed() == 0;
 	      }
 			}
 		}
@@ -345,16 +343,14 @@ public class ManagerUtils {
 						+ dm.getDisplayName() + " :\n" + dm.getTorrentFileName()
 						+ MessageText.getString("deletetorrent.message2");
 
-				MessageBoxShell mb = new MessageBoxShell(shell, title, text,
-						new String[] {
-							MessageText.getString("Button.yes"),
-							MessageText.getString("Button.no"),
-						}, 1);
+				MessageBoxShell mb = new MessageBoxShell(SWT.YES | SWT.NO, title, text);
+				mb.setDefaultButtonUsingStyle(SWT.NO);
 				mb.setRelatedObject(dm);
 				mb.setLeftImage(SWT.ICON_WARNING);
 
-				int result = mb.open();
-				if (result != 0) {
+				mb.open(null);
+				int result = mb.waitUntilClosed();
+				if (result != SWT.YES) {
 					if (deleteFailed != null) {
 						deleteFailed.runSupport();
 					}
@@ -374,17 +370,17 @@ public class ManagerUtils {
 							dm.getDisplayName()
 						});
 						
-				MessageBoxShell mb = new MessageBoxShell(shell, title, text,
-						new String[] {
-							MessageText.getString("Button.yes"),
-							MessageText.getString("Button.no"),
-						}, 1,"deletedata.noconfirm.key2",MessageText.getString("deletedata.noprompt"),false,0);
+				MessageBoxShell mb = new MessageBoxShell(SWT.YES | SWT.NO, title, text);
+				mb.setDefaultButtonUsingStyle(SWT.NO);
+				mb.setRemember("deletedata.noconfirm.key2", false,
+						MessageText.getString("deletedata.noprompt"));
 				mb.setRememberOnlyIfButton(0);
 				mb.setRelatedObject(dm);
 				mb.setLeftImage(SWT.ICON_WARNING);
 
-				int result = mb.open();
-				if (result != 0) {
+				mb.open(null);
+				int result = mb.waitUntilClosed();
+				if (result != SWT.YES) {
 					if (deleteFailed != null) {
 						deleteFailed.runSupport();
 					}
@@ -397,11 +393,14 @@ public class ManagerUtils {
 				bDeleteData, deleteFailed);
 	}
   
+  private static AsyncDispatcher async = new AsyncDispatcher(2000);
+  
   public static void asyncStopDelete(final DownloadManager dm,
 			final int stateAfterStopped, final boolean bDeleteTorrent,
 			final boolean bDeleteData, final AERunnable deleteFailed) {
 
-		new AEThread("asyncStop", true) {
+	  
+	async.dispatch(new AERunnable() {
 			public void runSupport() {
 
 				try {
@@ -423,7 +422,7 @@ public class ManagerUtils {
 					}
 				}
 			}
-		}.start();
+		});
 	}
   
   	public static void
@@ -431,14 +430,13 @@ public class ManagerUtils {
 		final DownloadManager	dm,
 		final int 				stateAfterStopped )
   	{
-    	new AEThread( "asyncStop", true )
-		{
+    	async.dispatch(new AERunnable() {
     		public void
 			runSupport()
     		{
     			dm.stopIt( stateAfterStopped, false, false );
     		}
-		}.start();
+		});
   	}
 
 	public static void asyncStartAll() {
diff --git a/org/gudy/azureus2/ui/swt/views/utils/VerticalAligner.java b/org/gudy/azureus2/ui/swt/views/utils/VerticalAligner.java
deleted file mode 100644
index 465b5de..0000000
--- a/org/gudy/azureus2/ui/swt/views/utils/VerticalAligner.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * File    : VerticalAligner.java
- * Created : 22 dec. 2003
- * By      : Olivier
- *
- * Copyright (C) 2004, 2005, 2006 Aelitis SAS, All rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details ( see the LICENSE file ).
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * AELITIS, SAS au capital de 46,603.30 euros,
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- */
-package org.gudy.azureus2.ui.swt.views.utils;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.ScrollBar;
-import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.config.ParameterListener;
-import org.gudy.azureus2.ui.swt.Utils;
-
-/** Workaround Eclipse Bug Bug 42416
- *   "[Platform Inconsistency] GC(Table) has wrong origin"
- *   
- *  Fixed in ~3226
- *
- */
-public class VerticalAligner {
-	private static boolean bFixGTKBug;
-
-	static {
-		COConfigurationManager.addAndFireParameterListener("SWT_bGTKTableBug",
-				new ParameterListener() {
-					public void parameterChanged(String parameterName) {
-						// some people switch from motif to gtk & back again, so make this
-						// only apply to GTK, even if it was enabled prior
-						bFixGTKBug = COConfigurationManager
-								.getBooleanParameter("SWT_bGTKTableBug")
-								&& Utils.isGTK && SWT.getVersion() < 3226;
-					}
-				});
-	}
-
-	public static int getTableAdjustVerticalBy(Table t) {
-		if (!bFixGTKBug || t == null || t.isDisposed())
-			return 0;
-		return -t.getHeaderHeight();
-	}
-
-	public static int getTableAdjustHorizontallyBy(Table t) {
-		if (!bFixGTKBug || t == null || t.isDisposed())
-			return 0;
-		ScrollBar sb = t.getHorizontalBar();
-		if (sb == null)
-			return 0;
-		return sb.getSelection();
-	}
-
-}
diff --git a/org/gudy/azureus2/ui/swt/welcome/WelcomeWindow.java b/org/gudy/azureus2/ui/swt/welcome/WelcomeWindow.java
index 42a0df2..4b908a7 100644
--- a/org/gudy/azureus2/ui/swt/welcome/WelcomeWindow.java
+++ b/org/gudy/azureus2/ui/swt/welcome/WelcomeWindow.java
@@ -62,7 +62,11 @@ public class WelcomeWindow {
   Shell shell;
   Color black,white,light,grey,green,blue,fg,bg;
   String sWhatsNew;
-  Font monospace; 
+  Font monospace;
+
+	private Composite cWhatsNew;
+
+	private Label labelLoading; 
   
   public WelcomeWindow(Shell parentShell) {
   	try {
@@ -88,7 +92,7 @@ public class WelcomeWindow {
     
     GridData data;
     
-    Composite cWhatsNew = new Composite(shell, SWT.BORDER);
+    cWhatsNew = new Composite(shell, SWT.BORDER);
     data = new GridData(GridData.FILL_BOTH);
     cWhatsNew.setLayoutData(data);
     cWhatsNew.setLayout(new FillLayout());
@@ -123,66 +127,33 @@ public class WelcomeWindow {
     Utils.centreWindow(shell);
     shell.layout();
     shell.open();    
-    fillWhatsNew(cWhatsNew);
+    pullWhatsNew(cWhatsNew);
   }
   
-  private void fillWhatsNew(Composite cWhatsNew) {
-  	String helpFile;
-
-  	Label label = new Label(cWhatsNew, SWT.CENTER);
-  	label.setText(MessageText.getString("installPluginsWizard.details.loading"));
+  private void pullWhatsNew(Composite cWhatsNew) {
+  	labelLoading = new Label(cWhatsNew, SWT.CENTER);
+  	labelLoading.setText(MessageText.getString("installPluginsWizard.details.loading"));
   	shell.layout(true, true);
   	shell.update();
   	
-		// Support external URLs for what's new
-		helpFile = MessageText.getString("window.welcome.file");
-		if (sWhatsNew == null || sWhatsNew.length() == 0) {
-			if (helpFile.toLowerCase().startsWith(Constants.SF_WEB_SITE)) {
-				sWhatsNew = getWhatsNew(helpFile);
-				if (shell.isDisposed()) {
-					return;
-				}
-			}
-		}
+  	getWhatsNew(1);
+  }
 
-		if (sWhatsNew == null || sWhatsNew.length() == 0) {
-  		helpFile = URL_WHATSNEW + "?version=" + Constants.AZUREUS_VERSION
-  				+ "&locale=" + Locale.getDefault().toString() + "&ui="
-  				+ COConfigurationManager.getStringParameter("ui");
-  
-  		sWhatsNew = getWhatsNew(helpFile);
-  		if (shell.isDisposed()) {
-  			return;
-  		}
-		}
-		
-		if (sWhatsNew == null || sWhatsNew.length() == 0) {
-			InputStream stream;
-			stream = getClass().getResourceAsStream(helpFile);
-			if (stream == null) {
-				String helpFullPath = "/org/gudy/azureus2/internat/whatsnew/" + helpFile;
-				stream = getClass().getResourceAsStream(helpFullPath);
-			}
-			if (stream == null) {
-				stream = getClass().getResourceAsStream("/ChangeLog.txt");
-			}
-			if (stream == null) {
-				sWhatsNew = "Welcome Window: Error loading resource: " + helpFile;
-			} else {
-				try {
-					sWhatsNew = FileUtil.readInputStreamAsString(stream, 65535, "utf8");
-					stream.close();
-				} catch (IOException e) {
-					Debug.out(e);
-				}
+  public void setWhatsNew() {
+  	Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				_setWhatsNew();
 			}
-		}
+		});
+  }
+
+  public void _setWhatsNew() {
 
 		if (sWhatsNew.indexOf("<html") >= 0 || sWhatsNew.indexOf("<HTML") >= 0) {
-			try {
-				Browser browser = new Browser(cWhatsNew, Utils.getInitialBrowserStyle(SWT.NONE));
+			Browser browser = Utils.createSafeBrowser(cWhatsNew, SWT.NONE);
+			if (browser != null) {	
 				browser.setText(sWhatsNew);
-			} catch (Throwable t) {
+			} else {
 				try {
 					File tempFile = File.createTempFile("AZU", ".html");
 					tempFile.deleteOnExit();
@@ -293,16 +264,58 @@ public class WelcomeWindow {
 			}
 		}
 		
-		label.dispose();
+		if (labelLoading != null && !labelLoading.isDisposed()) {
+			labelLoading.dispose();
+		}
 		shell.layout(true, true);
 	}
   
-  private String getWhatsNew(final String url) {
-		final String[] s = new String[1];
-		new AEThread("getWhatsNew", true) {
+  private void getWhatsNew(final int phase) {
+  	String helpFile = null;
+  	if (phase == 1) {
+  		helpFile = MessageText.getString("window.welcome.file");
 
-			public void runSupport() {
+			if (!helpFile.toLowerCase().startsWith(Constants.SF_WEB_SITE)) {
+				getWhatsNew(2);
+				return;
+			}
+  	} else if (phase == 2) {
+  		helpFile = URL_WHATSNEW + "?version=" + Constants.AZUREUS_VERSION
+			+ "&locale=" + Locale.getDefault().toString() + "&ui="
+			+ COConfigurationManager.getStringParameter("ui");
+  	} else {
+  		helpFile = MessageText.getString("window.welcome.file");
+
+			InputStream stream;
+			stream = getClass().getResourceAsStream(helpFile);
+			if (stream == null) {
+				String helpFullPath = "/org/gudy/azureus2/internat/whatsnew/" + helpFile;
+				stream = getClass().getResourceAsStream(helpFullPath);
+			}
+			if (stream == null) {
+				stream = getClass().getResourceAsStream("/ChangeLog.txt");
+			}
+			if (stream == null) {
+				sWhatsNew = "Welcome Window: Error loading resource: " + helpFile;
+			} else {
+				try {
+					sWhatsNew = FileUtil.readInputStreamAsString(stream, 65535, "utf8");
+					stream.close();
+				} catch (IOException e) {
+					Debug.out(e);
+				}
+			}
+			setWhatsNew();
+			return;
+  	}
+  	
+  	final String url = helpFile;
+  	
+		new AEThread2("getWhatsNew", true) {
 
+			public void run() {
+
+				String s;
 				ResourceDownloaderFactory rdf = ResourceDownloaderFactoryImpl.getSingleton();
 				try {
 					ResourceDownloader rd = rdf.create(new URL(url));
@@ -311,32 +324,34 @@ public class WelcomeWindow {
 					byte data[] = new byte[length];
 					is.read(data);
 					is.close();
-					s[0] = new String(data);
+					s = new String(data);
 				} catch (ResourceDownloaderException rde) {
 					// We don't need a stack trace - it's arguable that we even need any
 					// errors at all - the below line is better, but suppressed output might
 					// be better.
 					//Debug.outNoStack("Error downloading from " + url + ", " + rde, true);
-					s[0] = "";
+					s = "";
 				} catch (Exception e) {
 					Debug.out(e);
-					s[0] = "";
+					s = "";
 				}
-
-				if (!shell.isDisposed()) {
-					shell.getDisplay().wake();
+				sWhatsNew = s;
+				
+				if (sWhatsNew == null || sWhatsNew.length() == 0) {
+					getWhatsNew(phase + 1);
+					return;
 				}
-			}
 
-		}.start();
-		
-		while (!shell.isDisposed() && s[0] == null) {
-			if (!shell.getDisplay().readAndDispatch()) {
-				shell.getDisplay().sleep();
+				Utils.execSWTThread(new AERunnable() {
+					public void runSupport() {
+						if (cWhatsNew != null && !cWhatsNew.isDisposed()) {
+							setWhatsNew();
+						}
+					}
+				});
 			}
-		}
 
-		return s[0];
+		}.start();
 	}
   
   private void close() {
diff --git a/org/gudy/azureus2/ui/swt/win32/Win32UIEnhancer.java b/org/gudy/azureus2/ui/swt/win32/Win32UIEnhancer.java
index 392d1d8..6028673 100644
--- a/org/gudy/azureus2/ui/swt/win32/Win32UIEnhancer.java
+++ b/org/gudy/azureus2/ui/swt/win32/Win32UIEnhancer.java
@@ -21,20 +21,17 @@
 package org.gudy.azureus2.ui.swt.win32;
 
 import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.internal.Callback;
-import org.eclipse.swt.internal.win32.OS;
-import org.eclipse.swt.internal.win32.TCHAR;
+import org.eclipse.swt.internal.win32.*;
 import org.eclipse.swt.widgets.Shell;
 
 import org.gudy.azureus2.platform.win32.access.AEWin32Manager;
 
-import com.aelitis.azureus.core.drivedetector.DriveDetectedInfo;
-import com.aelitis.azureus.core.drivedetector.DriveDetector;
-import com.aelitis.azureus.core.drivedetector.DriveDetectorFactory;
+import com.aelitis.azureus.core.drivedetector.*;
 
 /**
  * @author TuxPaper
@@ -48,129 +45,164 @@ public class Win32UIEnhancer
 
 	public static final boolean DEBUG = false;
 
+	public static final int SHGFI_LARGEICON = 0x2;
+
 	public static final int WM_DEVICECHANGE = 0x219;
 
 	public static final int DBT_DEVICEARRIVAL = 0x8000;
+
 	public static final int DBT_DEVICEREMOVECOMPLETE = 0x8004;
-	
+
 	public static final int DBT_DEVTYP_VOLUME = 0x2;
 
-	private static int messageProc;
+	private static int messageProcInt;
 
-	private static  Callback messageCallback;
+	private static long messageProcLong;
+
+	private static Object /* Callback */messageCallback;
 
 	private static DriveDetectedInfo loc;
 
-	static String findProgramKey(String extension) {
-		if (extension == null)
-			SWT.error(SWT.ERROR_NULL_ARGUMENT);
-		if (extension.length() == 0)
-			return null;
-		if (extension.charAt(0) != '.')
-			extension = "." + extension; //$NON-NLS-1$
-		/* Use the character encoding for the default locale */
-		TCHAR key = new TCHAR(0, extension, true);
-		int[] phkResult = new int[1];
-		if (OS.RegOpenKeyEx(OS.HKEY_CLASSES_ROOT, key, 0, OS.KEY_READ, phkResult) != 0) {
-			return null;
-		}
-		int[] lpcbData = new int[1];
-		int result = OS.RegQueryValueEx(phkResult[0], null, 0, null, (TCHAR) null,
-				lpcbData);
-		if (result == 0) {
-			TCHAR lpData = new TCHAR(0, lpcbData[0] / TCHAR.sizeof);
-			result = OS.RegQueryValueEx(phkResult[0], null, 0, null, lpData, lpcbData);
-			if (result == 0)
-				return lpData.toString(0, lpData.strlen());
-		}
-		OS.RegCloseKey(phkResult[0]);
-		return null;
-	}
+	private static Class<?> claOS;
 
-    public static ImageData getBigImageData(String extension) {
-		String key = findProgramKey(extension);
-		if (key == null) {
-			return null;
-		}
+	private static boolean useLong;
+
+	private static Class<?> claCallback;
+
+	private static Constructor<?> constCallBack;
+
+	private static Method mCallback_getAddress;
+
+	private static Method mSetWindowLongPtr;
+
+	private static int OS_GWLP_WNDPROC;
+
+	private static Method mOS_memmove_byte;
+
+	private static Method mOS_memmove_int;
+
+	static {
+		try {
+			claOS = Class.forName("org.eclipse.swt.internal.win32.OS");
+
+			// public Callback (Object object, String method, int argCount)
+			claCallback = Class.forName("org.eclipse.swt.internal.Callback");
+			constCallBack = claCallback.getDeclaredConstructor(new Class[] {
+				Object.class,
+				String.class,
+				int.class
+			});
+			// public long /*int*/ getAddress ()
+			mCallback_getAddress = claCallback.getDeclaredMethod("getAddress",
+					new Class[] {});
 
-		/* Icon */
-		String DEFAULT_ICON = "\\DefaultIcon"; //$NON-NLS-1$
-		String iconName = getKeyValue(key + DEFAULT_ICON, true);
-		if (iconName == null)
-			iconName = ""; //$NON-NLS-1$
-
-		int nIconIndex = 0;
-		String fileName = iconName;
-		int index = iconName.indexOf(',');
-		if (index != -1) {
-			fileName = iconName.substring(0, index);
-			String iconIndex = iconName.substring(index + 1, iconName.length()).trim();
 			try {
-				nIconIndex = Integer.parseInt(iconIndex);
-			} catch (NumberFormatException e) {
+				//int /*long*/ SetWindowLongPtr (int /*long*/ hWnd, int nIndex, int /*long*/ dwNewLong) {
+				mSetWindowLongPtr = claOS.getMethod("SetWindowLongPtr",
+						new Class[] {
+							int.class,
+							int.class,
+							int.class
+						});
+
+				useLong = false;
+				
+				mOS_memmove_byte = claOS.getMethod("memmove", new Class[] {
+					byte[].class,
+					int.class,
+					int.class
+				});
+				mOS_memmove_int = claOS.getMethod("memmove", new Class[] {
+					int[].class,
+					int.class,
+					int.class
+				});
+			} catch (Exception e) {
+				e.printStackTrace();
+				mSetWindowLongPtr = claOS.getMethod("SetWindowLongPtr",
+						new Class[] {
+							long.class,
+							int.class,
+							long.class
+						});
+
+				useLong = true;
+				mOS_memmove_byte = claOS.getMethod("memmove", new Class[] {
+					byte[].class,
+					long.class,
+					int.class
+				});
+				mOS_memmove_int = claOS.getMethod("memmove", new Class[] {
+					int[].class,
+					int.class,
+					long.class
+				});
 			}
+
+			//OS.GWLP_WNDPROC
+			OS_GWLP_WNDPROC = ((Integer) claOS.getField("GWLP_WNDPROC").get(null)).intValue();
+		} catch (Throwable e) {
+			e.printStackTrace();
 		}
-		/* Use the character encoding for the default locale */
-		TCHAR lpszFile = new TCHAR(0, fileName, true);
-		int[] phiconSmall = null, phiconLarge = new int[1];
-		OS.ExtractIconEx(lpszFile, nIconIndex, phiconLarge, phiconSmall, 1);
-		if (phiconLarge[0] == 0) {
-			return null;
-		}
-		Image image = Image.win32_new(null, SWT.ICON, phiconLarge[0]);
-		ImageData imageData = image.getImageData();
-		image.dispose();
-		return imageData;
 	}
 
-	static String getKeyValue(String string, boolean expand) {
-		/* Use the character encoding for the default locale */
-		TCHAR key = new TCHAR(0, string, true);
-		int[] phkResult = new int[1];
-		if (OS.RegOpenKeyEx(OS.HKEY_CLASSES_ROOT, key, 0, OS.KEY_READ, phkResult) != 0) {
-			return null;
+	public static Image getFileIcon(File file, boolean big) {
+		int flags = OS.SHGFI_ICON;
+		flags |= big ? SHGFI_LARGEICON : OS.SHGFI_SMALLICON;
+		if (!file.exists()) {
+			flags |= OS.SHGFI_USEFILEATTRIBUTES;
 		}
-		String result = null;
-		int[] lpcbData = new int[1];
-		if (OS.RegQueryValueEx(phkResult[0], (TCHAR) null, 0, null, (TCHAR) null,
-				lpcbData) == 0) {
-			result = "";
-			int length = lpcbData[0] / TCHAR.sizeof;
-			if (length != 0) {
-				/* Use the character encoding for the default locale */
-				TCHAR lpData = new TCHAR(0, length);
-				if (OS.RegQueryValueEx(phkResult[0], null, 0, null, lpData, lpcbData) == 0) {
-					if (!OS.IsWinCE && expand) {
-						length = OS.ExpandEnvironmentStrings(lpData, null, 0);
-						if (length != 0) {
-							TCHAR lpDst = new TCHAR(0, length);
-							OS.ExpandEnvironmentStrings(lpData, lpDst, length);
-							result = lpDst.toString(0, Math.max(0, length - 1));
-						}
-					} else {
-						length = Math.max(0, lpData.length() - 1);
-						result = lpData.toString(0, length);
-					}
-				}
-			}
+		SHFILEINFO shfi = OS.IsUnicode ? (SHFILEINFO) new SHFILEINFOW()
+				: new SHFILEINFOA();
+		TCHAR pszPath = new TCHAR(0, file.getAbsolutePath(), true);
+		OS.SHGetFileInfo(pszPath, file.isDirectory() ? 16
+				: OS.FILE_ATTRIBUTE_NORMAL, shfi, SHFILEINFO.sizeof, flags);
+		if (shfi.hIcon != 0) {
+			Image image = Image.win32_new(null, SWT.ICON, shfi.hIcon);
+			return image;
 		}
-		if (phkResult[0] != 0)
-			OS.RegCloseKey(phkResult[0]);
-		return result;
+
+		return null;
 	}
-	
+
 	public static void initMainShell(Shell shell) {
 		//Canvas canvas = new Canvas(shell, SWT.NO_BACKGROUND | SWT.NO_TRIM);
 		//canvas.setVisible(false);
 		Shell subshell = new Shell(shell);
-		
 
-		messageCallback = new Callback (Win32UIEnhancer.class, "messageProc2", 4);
-		messageProc = messageCallback.getAddress ();
-		if (messageProc != 0) {
-			OS.SetWindowLongPtr (subshell.handle, OS.GWLP_WNDPROC, messageProc);
+		try {
+			messageCallback = constCallBack.newInstance(new Object[] {
+				Win32UIEnhancer.class,
+				"messageProc2",
+				4
+			});
+
+			if (useLong) {
+				Number n = (Number) mCallback_getAddress.invoke(messageCallback,
+						new Object[] {});
+				messageProcLong = n.longValue();
+				if (messageProcLong != 0) {
+					mSetWindowLongPtr.invoke(null, new Object[] {
+						subshell.handle,
+						OS_GWLP_WNDPROC,
+						messageProcLong
+					});
+				}
+			} else {
+				Number n = (Number) mCallback_getAddress.invoke(messageCallback,
+						new Object[] {});
+				messageProcInt = n.intValue();
+				if (messageProcInt != 0) {
+					mSetWindowLongPtr.invoke(null, new Object[] {
+						subshell.handle,
+						OS_GWLP_WNDPROC,
+						messageProcInt
+					});
+				}
+			}
+		} catch (Exception ex) {
+			ex.printStackTrace();
 		}
-		
 
 		File[] drives = AEWin32Manager.getAccessor(false).getUSBDrives();
 		if (drives != null) {
@@ -182,16 +214,34 @@ public class Win32UIEnhancer
 
 	static int /*long*/messageProc2(int /*long*/hwnd, int /*long*/msg,
 			int /*long*/wParam, int /*long*/lParam) {
+		return (int) messageProc2(hwnd, msg, (long) wParam, (long) lParam);
+	}
+
+	static long /*int*/messageProc2(long /*int*/hwnd, long /*int*/msg,
+			long /*int*/wParam, long /*int*/lParam) {
 		try {
 			// I'll clean this up soon
 			switch ((int) /*64*/msg) {
 				case WM_DEVICECHANGE:
 					if (wParam == DBT_DEVICEARRIVAL) {
 						int[] st = new int[3];
-						OS.memmove(st, lParam, 12);
+						if (useLong) {
+  						mOS_memmove_int.invoke(null, new Object[] {
+  							st,
+  							lParam,
+  							(long) 12
+  						});
+						} else {
+  						mOS_memmove_int.invoke(null, new Object[] {
+  							st,
+  							(int) lParam,
+  							(int) 12
+  						});
+						}
 
 						if (DEBUG) {
-							System.out.println("Arrival: " + st[0] + "/" + st[1] + "/" + st[2]);
+							System.out.println("Arrival: " + st[0] + "/" + st[1] + "/"
+									+ st[2]);
 						}
 
 						if (st[1] == DBT_DEVTYP_VOLUME) {
@@ -200,7 +250,20 @@ public class Win32UIEnhancer
 							}
 
 							byte b[] = new byte[st[0]];
-							OS.memmove(b, lParam, st[0]);
+							
+							if (useLong) {
+  							mOS_memmove_byte.invoke(null, new Object[] {
+  								b,
+  								lParam,
+  								(int) st[0]
+  							});
+							} else {
+  							mOS_memmove_byte.invoke(null, new Object[] {
+  								b,
+  								(int) lParam,
+  								(int) st[0]
+  							});
+							}
 							long unitMask = b[12] + (b[13] << 8) + (b[14] << 16)
 									+ (b[14] << 24);
 							char letter = '?';
@@ -220,7 +283,19 @@ public class Win32UIEnhancer
 
 					} else if (wParam == DBT_DEVICEREMOVECOMPLETE) {
 						int[] st = new int[3];
-						OS.memmove(st, lParam, 12);
+						if (useLong) {
+  						mOS_memmove_int.invoke(null, new Object[] {
+  							st,
+  							lParam,
+  							(long) 12
+  						});
+						} else {
+  						mOS_memmove_int.invoke(null, new Object[] {
+  							st,
+  							(int) lParam,
+  							(int) 12
+  						});
+						}
 
 						if (DEBUG) {
 							System.out.println("Remove: " + st[0] + "/" + st[1] + "/" + st[2]);
@@ -232,7 +307,19 @@ public class Win32UIEnhancer
 							}
 
 							byte b[] = new byte[st[0]];
-							OS.memmove(b, lParam, st[0]);
+							if (useLong) {
+  							mOS_memmove_byte.invoke(null, new Object[] {
+  								b,
+  								lParam,
+  								(int) st[0]
+  							});
+							} else {
+  							mOS_memmove_byte.invoke(null, new Object[] {
+  								b,
+  								(int) lParam,
+  								(int) st[0]
+  							});
+							}
 							long unitMask = b[12] + (b[13] << 8) + (b[14] << 16)
 									+ (b[14] << 24);
 							char letter = '?';
diff --git a/org/gudy/azureus2/ui/swt/wizard/Wizard.java b/org/gudy/azureus2/ui/swt/wizard/Wizard.java
index aa9bf01..e61579f 100644
--- a/org/gudy/azureus2/ui/swt/wizard/Wizard.java
+++ b/org/gudy/azureus2/ui/swt/wizard/Wizard.java
@@ -34,7 +34,6 @@ import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
@@ -46,7 +45,7 @@ import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 public class Wizard {
 
 	private final static int DEFAULT_WIDTH = 500;
-  List		listeners = new ArrayList();
+  List<WizardListener>		listeners = new ArrayList<WizardListener>(1);
   
   Display display;
   Shell wizardWindow;
@@ -373,16 +372,6 @@ public class Wizard {
     insureSize();
     Utils.centreWindow( wizardWindow );
     wizardWindow.open();
-    
-    while (!wizardWindow.isDisposed()) {
-    	try {
-  			if (!display.readAndDispatch()) {
-  				display.sleep();
-  			}
-    	} catch (Exception e) {
-    		Debug.out(e);
-    	}
-		}
   }
 
   public Shell getWizardWindow() {
@@ -420,7 +409,7 @@ public class Wizard {
   	
   	for (int i=0;i<listeners.size();i++){
   		
-  		((WizardListener)listeners.get(i)).closed();
+  		listeners.get(i).closed();
   	}
   }  
   /**
diff --git a/org/gudy/azureus2/ui/systray/SystemTraySWT.java b/org/gudy/azureus2/ui/systray/SystemTraySWT.java
index 20b9679..1ca1bce 100644
--- a/org/gudy/azureus2/ui/systray/SystemTraySWT.java
+++ b/org/gudy/azureus2/ui/systray/SystemTraySWT.java
@@ -21,6 +21,7 @@
 package org.gudy.azureus2.ui.systray;
 
 import java.util.List;
+import java.util.Locale;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.MenuEvent;
@@ -28,20 +29,25 @@ import org.eclipse.swt.events.MenuListener;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.*;
 
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.global.GlobalManager;
 import org.gudy.azureus2.core3.global.GlobalManagerStats;
 import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.internat.MessageText.MessageTextListener;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.ui.common.util.MenuItemManager;
-import org.gudy.azureus2.ui.swt.*;
+import org.gudy.azureus2.ui.swt.MenuBuildUtils;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 import org.gudy.azureus2.ui.swt.mainwindow.SelectableSpeedMenu;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 
 import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.ui.common.updater.UIUpdatableAlways;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
@@ -52,7 +58,7 @@ import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
  *
  */
 public class SystemTraySWT
-	implements UIUpdatableAlways
+	implements UIUpdatableAlways, MessageTextListener
 {
 
 	protected static AzureusCore core = null;
@@ -73,6 +79,17 @@ public class SystemTraySWT
 
 	protected GlobalManager gm = null;
 
+	private String seedingKeyVal;
+	private String downloadingKeyVal;
+
+	private String dlAbbrKeyVal;
+
+	protected String ulAbbrKeyVal;
+	
+	long interval = 0;
+
+	protected boolean enableTooltip;
+
 	public SystemTraySWT() {
 		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(AzureusCore core) {
@@ -80,6 +97,21 @@ public class SystemTraySWT
 				gm = core.getGlobalManager();
 			}
 		});
+		
+		COConfigurationManager.addAndFireParameterListener(
+				"ui.systray.tooltip.enable", new ParameterListener() {
+					public void parameterChanged(String parameterName) {
+						enableTooltip = COConfigurationManager.getBooleanParameter(parameterName);
+						if (enableTooltip) {
+							MessageText.addAndFireListener(SystemTraySWT.this);
+						} else {
+							MessageText.removeListener(SystemTraySWT.this);
+							if (trayItem != null && !trayItem.isDisposed()) {
+								trayItem.setToolTipText(null);
+							}
+						}
+					}
+				});
 
 		uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
 		display = SWTThread.getInstance().getDisplay();
@@ -331,6 +363,9 @@ public class SystemTraySWT
 
 	// @see com.aelitis.azureus.ui.common.updater.UIUpdatable#updateUI()
 	public void updateUI() {
+		if (interval++ % 10 > 0) {
+			return;
+		}
 		if (trayItem.isDisposed()) {
 			uiFunctions.getUIUpdater().removeUpdater(this);
 			return;
@@ -339,51 +374,42 @@ public class SystemTraySWT
 			return;
 		}
 
-		GlobalManagerStats stats = gm.getStats();
-		List managers = gm.getDownloadManagers();
-		//StringBuffer toolTip = new StringBuffer("Azureus - ");//$NON-NLS-1$
-		StringBuffer toolTip = new StringBuffer();
-		int seeding = 0;
-		int downloading = 0;
-
-		for (int i = 0; i < managers.size(); i++) {
-			DownloadManager manager = (DownloadManager) managers.get(i);
-			int state = manager.getState();
-			if (state == DownloadManager.STATE_DOWNLOADING)
-				downloading++;
-			if (state == DownloadManager.STATE_SEEDING)
-				seeding++;
-		}
-
-		// something went funny here across Java versions, leading " " got lost
-
-		String seeding_text = MessageText.getString("SystemTray.tooltip.seeding").replaceAll(
-				"%1", "" + seeding);
-		String downloading_text = MessageText.getString(
-				"SystemTray.tooltip.downloading").replaceAll("%1", "" + downloading);
-
-		/*	if ( !seeding_text.startsWith(" " )){
-		 seeding_text = " " + seeding_text;
-		 }*/
-		if (!downloading_text.startsWith(" ")) {
-			downloading_text = " " + downloading_text;
+		if (enableTooltip) {
+  		GlobalManagerStats stats = gm.getStats();
+  		List<?> managers = gm.getDownloadManagers();
+
+  		StringBuffer toolTip = new StringBuffer();
+  		int seeding = 0;
+  		int downloading = 0;
+  
+  		// OMG this must be slow on 10k lists
+  		for (int i = 0; i < managers.size(); i++) {
+  			DownloadManager manager = (DownloadManager) managers.get(i);
+  			int state = manager.getState();
+  			if (state == DownloadManager.STATE_DOWNLOADING)
+  				downloading++;
+  			if (state == DownloadManager.STATE_SEEDING)
+  				seeding++;
+  		}
+  
+  		String seeding_text = seedingKeyVal.replaceAll("%1", "" + seeding);
+  		String downloading_text = downloadingKeyVal.replaceAll("%1", "" + downloading);
+  
+  		toolTip.append(seeding_text).append(downloading_text).append("\n");
+  		toolTip.append(dlAbbrKeyVal).append(
+  				" ");
+  
+  		toolTip.append(DisplayFormatters.formatDataProtByteCountToKiBEtcPerSec(
+  				stats.getDataReceiveRate(), stats.getProtocolReceiveRate()));
+  		
+  		toolTip.append(", ").append(ulAbbrKeyVal).append(" ");
+  		toolTip.append(DisplayFormatters.formatDataProtByteCountToKiBEtcPerSec(
+  				stats.getDataSendRate(), stats.getProtocolSendRate()));
+  		
+  		
+  		trayItem.setToolTipText(toolTip.toString());
 		}
 
-		toolTip.append(seeding_text).append(downloading_text).append("\n");
-		toolTip.append(MessageText.getString("ConfigView.download.abbreviated")).append(
-				" ");
-
-		toolTip.append(DisplayFormatters.formatDataProtByteCountToKiBEtcPerSec(
-				stats.getDataReceiveRate(), stats.getProtocolReceiveRate()));
-		
-		toolTip.append(", ").append(
-				MessageText.getString("ConfigView.upload.abbreviated")).append(" ");
-		toolTip.append(DisplayFormatters.formatDataProtByteCountToKiBEtcPerSec(
-				stats.getDataSendRate(), stats.getProtocolSendRate()));
-		
-		
-		trayItem.setToolTipText(toolTip.toString());
-
 		//Why should we refresh the image? it never changes ...
 		//and is a memory bottleneck for some non-obvious reasons.
 		//trayItem.setImage(ImageRepository.getImage("azureus"));   
@@ -406,4 +432,15 @@ public class SystemTraySWT
 	public String getUpdateUIName() {
 		return "SystemTraySWT";
 	}
+
+	public void localeChanged(Locale oldLocale, Locale newLocale) {
+		seedingKeyVal = MessageText.getString("SystemTray.tooltip.seeding");
+		downloadingKeyVal = MessageText.getString("SystemTray.tooltip.downloading");
+		if (!downloadingKeyVal.startsWith(" ")) {
+			downloadingKeyVal = " " + downloadingKeyVal;
+		}
+
+		dlAbbrKeyVal = MessageText.getString("ConfigView.download.abbreviated");
+		ulAbbrKeyVal = MessageText.getString("ConfigView.upload.abbreviated");
+	}
 }
diff --git a/org/gudy/azureus2/ui/webplugin/WebPlugin.java b/org/gudy/azureus2/ui/webplugin/WebPlugin.java
index 8713213..415a61c 100644
--- a/org/gudy/azureus2/ui/webplugin/WebPlugin.java
+++ b/org/gudy/azureus2/ui/webplugin/WebPlugin.java
@@ -40,20 +40,29 @@ import org.gudy.azureus2.plugins.ui.*;
 import org.gudy.azureus2.plugins.ui.config.*;
 import org.gudy.azureus2.plugins.ui.model.*;
 
+import com.aelitis.azureus.core.pairing.PairedService;
+import com.aelitis.azureus.core.pairing.PairingConnectionData;
+import com.aelitis.azureus.core.pairing.PairingManager;
+import com.aelitis.azureus.core.pairing.PairingManagerFactory;
+import com.aelitis.azureus.core.pairing.PairingManagerListener;
 import com.aelitis.azureus.plugins.upnp.UPnPPlugin;
 
 public class 
 WebPlugin
 	implements Plugin, TrackerWebPageGenerator
 {
+	public static final String	PR_DISABLABLE				= "Disablable";					// Boolean
 	public static final String	PR_PORT						= "Port";						// Integer
 	public static final String	PR_BIND_IP					= "Bind IP";					// String
 	public static final String	PR_ROOT_RESOURCE			= "Root Resource";				// String
+	public static final String	PR_ROOT_DIR					= "Root Dir";					// String
+	public static final String	PR_ACCESS					= "Access";						// String
 	public static final String	PR_LOG						= "DefaultLoggerChannel";		// LoggerChannel
 	public static final String	PR_CONFIG_MODEL				= "DefaultConfigModel";			// BasicPluginConfigModel
 	public static final String	PR_VIEW_MODEL				= "DefaultViewModel";			// BasicPluginViewModel
 	public static final String	PR_HIDE_RESOURCE_CONFIG		= "DefaultHideResourceConfig";	// Boolean
 	public static final String	PR_ENABLE_KEEP_ALIVE		= "DefaultEnableKeepAlive";		// Boolean
+	public static final String	PR_PAIRING_SID				= "PairingSID";					// String
 	
 	public static final String	PROPERTIES_MIGRATED		= "Properties Migrated";
 	public static final String	CONFIG_MIGRATED			= "Config Migrated";
@@ -61,11 +70,17 @@ WebPlugin
 	public static final String	CONFIG_PASSWORD_ENABLE			= "Password Enable";
 	public        final boolean	CONFIG_PASSWORD_ENABLE_DEFAULT	= false;
 	
-	public static final String	CONFIG_USER				= "User";
-	public        final String	CONFIG_USER_DEFAULT		= "";
+	public static final String	CONFIG_PAIRING_ENABLE			= "Pairing Enable";
+	public        final boolean	CONFIG_PAIRING_ENABLE_DEFAULT	= true;
+
+	public static final String	CONFIG_ENABLE					= "Enable";
+	public static final boolean	CONFIG_ENABLE_DEFAULT			= true;
+	
+	public static final String	CONFIG_USER						= "User";
+	public        final String	CONFIG_USER_DEFAULT				= "";
 	
-	public static final String	CONFIG_PASSWORD			= "Password";
-	public        final byte[]	CONFIG_PASSWORD_DEFAULT	= {};
+	public static final String	CONFIG_PASSWORD					= "Password";
+	public        final byte[]	CONFIG_PASSWORD_DEFAULT			= {};
 	
 	public static final String 	CONFIG_PORT						= PR_PORT;
 	public int			 		CONFIG_PORT_DEFAULT				= 8089;
@@ -82,8 +97,8 @@ WebPlugin
 	public static final String 	CONFIG_HOME_PAGE				= "Home Page";
 	public        final String 	CONFIG_HOME_PAGE_DEFAULT		= "index.html";
 	
-	public static final String 	CONFIG_ROOT_DIR					= "Root Dir";
-	public        final String 	CONFIG_ROOT_DIR_DEFAULT			= "";
+	public static final String 	CONFIG_ROOT_DIR					= PR_ROOT_DIR;
+	public        		String 	CONFIG_ROOT_DIR_DEFAULT			= "";
 	
 	public static final String 	CONFIG_ROOT_RESOURCE			= PR_ROOT_RESOURCE;
 	public              String 	CONFIG_ROOT_RESOURCE_DEFAULT	= "";
@@ -92,8 +107,8 @@ WebPlugin
 	public static final String 	CONFIG_MODE_FULL				= "full";
 	public        final String 	CONFIG_MODE_DEFAULT				= CONFIG_MODE_FULL;
 	
-	public static final String 	CONFIG_ACCESS					= "Access";
-	public        final String 	CONFIG_ACCESS_DEFAULT			= "all";
+	public static final String 	CONFIG_ACCESS					= PR_ACCESS;
+	public        		String 	CONFIG_ACCESS_DEFAULT			= "all";
 	
 	protected static final String	NL			= "\r\n";
 	
@@ -106,6 +121,9 @@ WebPlugin
 	private BasicPluginViewModel 	view_model;
 	private BasicPluginConfigModel	config_model;
 	
+	private IntParameter			param_port;
+	private StringListParameter		param_protocol;
+	
 	private String				home_page;
 	private String				file_root;
 	private String				resource_root;
@@ -157,6 +175,20 @@ WebPlugin
 			CONFIG_ROOT_RESOURCE_DEFAULT	= pr_root_resource;
 		}
 		
+		String	pr_root_dir = (String)properties.get( PR_ROOT_DIR );
+		
+		if( pr_root_dir != null ){
+			
+			CONFIG_ROOT_DIR_DEFAULT	= pr_root_dir;
+		}
+		
+		String	pr_access = (String)properties.get( PR_ACCESS );
+		
+		if( pr_access != null ){
+			
+			CONFIG_ACCESS_DEFAULT	= pr_access;
+		}
+		
 		Boolean	pr_hide_resource_config = (Boolean)properties.get( PR_HIDE_RESOURCE_CONFIG );
 		
 		log = (LoggerChannel)properties.get( PR_LOG );
@@ -317,12 +349,28 @@ WebPlugin
 			plugin_config.save();
 		}
 		
-		config_model.addLabelParameter2( "webui.restart.info" );
+		LabelParameter param_info = config_model.addLabelParameter2( "webui.restart.info" );
+
+		Boolean	disablable = (Boolean)properties.get( PR_DISABLABLE );
+		
+		boolean	enabled = true;
+		
+		BooleanParameter	param_enable = null;
+		
+		if ( disablable != null && disablable ){
+			
+			param_enable = 
+				config_model.addBooleanParameter2( CONFIG_ENABLE, "webui.enable", CONFIG_ENABLE_DEFAULT );
 
-		IntParameter	param_port = config_model.addIntParameter2(		CONFIG_PORT, "webui.port", CONFIG_PORT_DEFAULT );
+			enabled	= param_enable.getValue();
+		}
+			// connection group
+		
+		param_port = config_model.addIntParameter2(		CONFIG_PORT, "webui.port", CONFIG_PORT_DEFAULT );
+		
 		StringParameter	param_bind = config_model.addStringParameter2(	CONFIG_BIND_IP, "webui.bindip", CONFIG_BIND_IP_DEFAULT );
 		
-		StringListParameter	param_protocol = 
+		param_protocol = 
 			config_model.addStringListParameter2(
 					CONFIG_PROTOCOL, "webui.protocol", new String[]{ "http", "https" }, CONFIG_PROTOCOL_DEFAULT );
 		
@@ -333,6 +381,75 @@ WebPlugin
 							"webui.upnpenable",
 							CONFIG_UPNP_ENABLE_DEFAULT );
 
+		final String p_sid = (String)properties.get( PR_PAIRING_SID );
+		
+		final LabelParameter	pairing_info;
+		final BooleanParameter	pairing_enable;
+		
+		if ( p_sid != null ){
+			
+			PairingManager pm = PairingManagerFactory.getSingleton();
+
+			pairing_info = config_model.addLabelParameter2( "webui.pairing.info." + (pm.isEnabled()?"y":"n"));
+				
+			pairing_enable = 
+				config_model.addBooleanParameter2( 
+						CONFIG_PAIRING_ENABLE, 
+								"webui.pairingenable",
+								CONFIG_PAIRING_ENABLE_DEFAULT );
+
+			pairing_enable.addListener(
+				new ParameterListener()
+				{
+					public void 
+					parameterChanged(
+						Parameter param ) 
+					{
+						setupPairing( p_sid, pairing_enable.getValue());
+					}
+				});
+			
+			pairing_enable.setEnabled( pm.isEnabled());
+			
+			pm.addListener(
+				new PairingManagerListener()
+				{
+					public void 
+					somethingChanged(
+						PairingManager pm ) 
+					{
+						pairing_info.setLabelKey( "webui.pairing.info." + (pm.isEnabled()?"y":"n"));
+
+						pairing_enable.setEnabled( pm.isEnabled());
+					}		
+				});
+			
+			setupPairing( p_sid, pairing_enable.getValue());
+			
+			ParameterListener update_pairing_listener = 
+				new ParameterListener()
+				{
+					public void 
+					parameterChanged(
+						Parameter param ) 
+					{
+						updatePairing( p_sid );
+					}
+				};
+				
+			param_port.addListener( update_pairing_listener );
+			param_protocol.addListener( update_pairing_listener );
+		}else{
+			pairing_info	= null;
+			pairing_enable 	= null;
+		}
+			
+		config_model.createGroup(
+			"ConfigView.section.server",
+			new Parameter[]{
+				param_port, param_bind, param_protocol, upnp_enable, pairing_info, pairing_enable,
+			});
+		
 		StringParameter	param_home 		= config_model.addStringParameter2(	CONFIG_HOME_PAGE, "webui.homepage", CONFIG_HOME_PAGE_DEFAULT );
 		StringParameter	param_rootdir 	= config_model.addStringParameter2(	CONFIG_ROOT_DIR, "webui.rootdir", CONFIG_ROOT_DIR_DEFAULT );
 		StringParameter	param_rootres	= config_model.addStringParameter2(	CONFIG_ROOT_RESOURCE, "webui.rootres", CONFIG_ROOT_RESOURCE_DEFAULT );
@@ -344,12 +461,15 @@ WebPlugin
 			param_rootres.setVisible( false );
 		}
 		
-		config_model.addLabelParameter2( "webui.mode.info" ); 
-		config_model.addStringListParameter2(	
+			// access group
+		
+		LabelParameter a_label1 = config_model.addLabelParameter2( "webui.mode.info" ); 
+		StringListParameter param_mode = 
+			config_model.addStringListParameter2(	
 					CONFIG_MODE, "webui.mode", new String[]{ "full", "view" }, CONFIG_MODE_DEFAULT );
 		
 		
-		config_model.addLabelParameter2( "webui.access.info" );
+		LabelParameter a_label2 = config_model.addLabelParameter2( "webui.access.info" );
 		StringParameter	param_access	= config_model.addStringParameter2(	CONFIG_ACCESS, "webui.access", CONFIG_ACCESS_DEFAULT );
 		
 		
@@ -375,6 +495,33 @@ WebPlugin
 		pw_enable.addEnabledOnSelection( user_name );
 		pw_enable.addEnabledOnSelection( password );
 		
+
+		config_model.createGroup(
+			"webui.group.access",
+			new Parameter[]{
+				a_label1, param_mode, a_label2, param_access,
+				pw_enable, user_name, password,
+			});
+			    
+		if ( !enabled ){
+			
+			Parameter[] params = config_model.getParameters();
+			
+			for ( Parameter param: params ){
+				
+				if ( param == param_enable || param == param_info ){
+					
+					continue;
+				}
+				
+				param.setEnabled( false );
+			}
+			
+			return;
+		}
+		
+			// end config
+		
 		tracker = plugin_interface.getTracker();
 		
 		home_page = param_home.getValue().trim();
@@ -419,8 +566,29 @@ WebPlugin
 				
 			}else{
 				
-				file_root = SystemProperties.getUserPath() + "web" + File.separator + root_dir;
+				if ( File.separatorChar != '/' && root_dir.contains( "/" )){
+					
+					root_dir = root_dir.replace( '/', File.separatorChar );
+				}
+				
+					// try relative to plugin dir
 				
+				file_root = plugin_interface.getPluginDirectoryName();
+
+				if ( file_root != null ){
+					
+					file_root = file_root + File.separator + root_dir;
+					
+					if ( !new File(file_root).exists()){
+						
+						file_root = null;
+					}
+				}
+				
+				if ( file_root == null ){
+					
+					file_root = SystemProperties.getUserPath() + "web" + File.separator + root_dir;
+				}
 			}
 		}
 
@@ -517,7 +685,7 @@ WebPlugin
 		}
 		
 		log.log( 	LoggerChannel.LT_INFORMATION, 
-					"acceptable IP range = " +
+					"Acceptable IP range = " +
 						( ip_range==null?
 							(ip_range_all?"all":"local"):
 							(ip_range.getStartIP() + " - " + ip_range.getEndIP())));
@@ -627,6 +795,82 @@ WebPlugin
 			});
 	}
 	
+	protected void
+	setupPairing(
+		String		sid,
+		boolean		enable )
+	{
+		PairingManager pm = PairingManagerFactory.getSingleton();
+		
+		PairedService service = pm.getService( sid );
+		
+		if ( enable ){
+			
+			if ( service == null ){
+				
+				service =  pm.addService( sid ); 
+				
+				PairingConnectionData cd = service.getConnectionData();
+
+				try{					
+					updatePairing( cd );
+				
+				}finally{
+				
+					cd.sync();
+				}
+			}
+		}else{
+			
+			if ( service != null ){
+				
+				service.remove();
+			}
+		}
+	}
+		
+	protected void
+	updatePairing(
+		String		sid )
+	{
+		PairingManager pm = PairingManagerFactory.getSingleton();
+		
+		PairedService service = pm.getService( sid );
+		
+		if ( service != null ){
+			
+			PairingConnectionData cd = service.getConnectionData();
+			
+			try{
+				updatePairing( cd );
+				
+			}finally{
+				
+				cd.sync();
+			}
+		}
+	}
+
+	protected void
+	updatePairing(
+		PairingConnectionData		cd )
+	{
+		cd.setAttribute( PairingConnectionData.ATTR_PORT, 		String.valueOf( param_port.getValue()));
+		cd.setAttribute( PairingConnectionData.ATTR_PROTOCOL, 	param_protocol.getValue());
+	}
+
+	protected int
+	getPort()
+	{
+		return( param_port.getValue());
+	}
+	
+	protected String
+	getProtocol()
+	{
+		return( param_protocol.getValue());
+	}
+	
 	public boolean
 	generateSupport(
 		TrackerWebPageRequest		request,
@@ -787,4 +1031,19 @@ WebPlugin
 	protected BasicPluginViewModel getViewModel() {
 		return this.view_model;
 	}
+	
+	protected void
+	log(
+		String	str )
+	{
+		log.log( str );
+	}
+	
+	protected void
+	log(
+		String		str,
+		Throwable 	e )
+	{
+		log.log( str, e );
+	}
 }
diff --git a/org/gudy/azureus2/update/CorePatchLevel.java b/org/gudy/azureus2/update/CorePatchLevel.java
index c213c10..d36556b 100644
--- a/org/gudy/azureus2/update/CorePatchLevel.java
+++ b/org/gudy/azureus2/update/CorePatchLevel.java
@@ -38,8 +38,10 @@ CorePatchLevel
 	
 		// Level 1: 2302 - fix for DHT version propagation problem
 		// Level 2: 2306 - fix for SF mirror parsing problem for core updates
+		// Level 3: 4208 - fix for OSX Snow Leopard torrent opening problem
+		// Level 4: 4208 - fix for OSX Snow Leopard torrent opening problem and UI hang on torrent with Tor URL add
 	
-	public static final int	PATCH_LEVEL	= 2;
+	public static final int	PATCH_LEVEL	= 4;
 	
 	public static int
 	getCurrentPatchLevel()
diff --git a/org/gudy/azureus2/update/CoreUpdateChecker.java b/org/gudy/azureus2/update/CoreUpdateChecker.java
index c1ade9d..a19e928 100644
--- a/org/gudy/azureus2/update/CoreUpdateChecker.java
+++ b/org/gudy/azureus2/update/CoreUpdateChecker.java
@@ -191,7 +191,7 @@ CoreUpdateChecker
 			}
 			
 			//latest_version 		= "3.0.0.3";
-			//latest_file_name	= "http://torrents.aelitis.com:88/torrents/Azureus2.5.0.0.jar.torrent";
+			//latest_file_name	= "http://torrent.vuze.com:88/torrents/Azureus2.5.0.0.jar.torrent";
 			//latest_file_name	= "Azureus2.5.0.0.jar.torrent";
 			
 			String	msg = "Core: latest_version = '" + latest_version + "', file = '" + latest_file_name + "'";
@@ -761,7 +761,7 @@ CoreUpdateChecker
 					try{
 						
 						res.add( new URL( mirror + latest_file_name ));
-						// res.add( new URL( "http://torrents.aelitis.com:88/torrents/Azureus2.4.0.2_signed.jar.torrent" ));
+						// res.add( new URL( "http://torrent.vuze.com:88/torrents/Azureus2.4.0.2_signed.jar.torrent" ));
 						
 					}catch(Throwable e){
 						


hooks/post-receive
-- 
Azureus/Vuze packaging for Debian



More information about the pkg-java-commits mailing list